﻿#include "embdata.h"
#include "main.h"
#include "sharedviews/setcontrolstyle.h"

const int headNum = 5; // 机头数
static int emb_showDirX = (1);// X向显示坐标和数据坐标的差异
static int emb_showDirY = (1);// Y向显示坐标和数据坐标的差异

EmbData::EmbData()
{
    m_pEmbDs16Head = new DataDs16FileHead();
    m_penHeadPix.resize(5);
    m_penPoint.resize(5);
    m_winnums = 0;
    clear();
}

EmbData::~EmbData()
{
    clear();
    if(m_pEmbDs16Head != NULL)
    {
        delete m_pEmbDs16Head;
    }
}

void EmbData::clear()
{
    m_maxX = 0;
    m_minX = 0;
    m_maxY = 0;
    m_minY = 0;
    m_fileid = 0;

    m_spaceX = 0;
    m_spaceY = 0;

    m_penX = 0;
    m_penY = 0;

    m_embDs16Data.clear();

    m_editedflag = 0;
    m_filePath.clear();
    m_factor = 0;

    m_dispDatFront.clear();//飞梭机前排数据
    m_dispDatMiddle.clear();//飞梭机中排数据
    m_dispDatBehind.clear();//飞梭机后排数据

    m_dispMinX = S32_MAX;
    m_dispMaxX = S32_MIN;
    m_dispMinY = S32_MAX;
    m_dispMaxY = S32_MIN;

    memset(m_pEmbDs16Head,0,sizeof(DataDs16FileHead));
}

QByteArray & EmbData::getDsDat()
{
    //qDebug()<<"m_editedflag"<<m_editedflag;
    if(m_editedflag != 0)
    {
        createEmbDs16FromAbs();
    }

    return m_embDs16Data;
}

QByteArray EmbData::getDispDat(double showWidth,double showHeight)
{
    QByteArray dispDat;

    ViewItem dispItem;
    dispDat.clear();//显示绘图用的数据（需要转换）

    // ds16数据
    int size = m_embDs16Data.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        return dispDat;
    }
    DataDs16FileHead * pDsHead = (DataDs16FileHead *)(m_embDs16Data.data());
    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        return dispDat;
    }
    int stepsize = datasize/sizeof(Ds16Item);
    if (stepsize <= 0)
    {
        return dispDat;
    }

    double width = showWidth;
    double height = showHeight;

    double dpx = showWidth / 2.0;
    double dpy = showHeight / 2.0;

    Ds16Item * ds16DataPtr;
    Ds16Item * pData = (Ds16Item *)(m_embDs16Data.data() + sizeof(DataDs16FileHead));
    ds16DataPtr = pData;

    // 显示花样图形
    u8 ctrlByte;
    u8 attrByte;
    int dx;
    int dy;
    int dr;

    double datposx, datposy, datposr, firstx, firsty;
    double curx, cury, curr, prex, prey;
    curx = cury = curr = prex = prey = 0;

    double unit = 100.0;

    datposx = pDsHead->beginX;
    datposy = pDsHead->beginY;
    datposr = pDsHead->beginR;

    firstx = pDsHead->beginX;
    firsty = pDsHead->beginY;

    curx = (datposx - firstx)/unit + dpx;
    cury = (datposy - firsty)/unit + dpy;

    if(g_emMacType == MACHINE_FLYFLATCUTTING ||
            g_emMacType == MACHINE_THICK_WIRING ||
            g_emMacType == MACHINE_DRAWING ||
            g_emMacType == MACHINE_MULTINEEDLEROTARY ||
            g_emMacType == MACHINE_HIGHSPEEDSINGLEQUI)
    {
        emb_showDirY = -1;
    }

    if (emb_showDirX == -1)
    {
        curx = width - curx;
    }
    if (emb_showDirY == -1)
    {
        cury = height - cury;
    }

    double maxX = S32_MIN;
    double maxY = S32_MIN;
    double minX = S32_MAX;
    double minY = S32_MAX;

    for (int i = 0; i < stepsize; i++)
    {
        prex = curx;
        prey = cury;

        // 读入一个针步数据
        ctrlByte = ds16DataPtr->ctrl;
        attrByte = ds16DataPtr->attr;
        dx = ds16DataPtr->dx;
        dy = ds16DataPtr->dy;
        dr = ds16DataPtr->dr;

        datposx += dx;
        datposy += dy;
        datposr += dr;

        curx = (datposx - firstx)/unit + dpx;
        cury = (datposy - firsty)/unit + dpy;

        if (emb_showDirX == -1)
        {
            curx = width - curx;
        }
        if (emb_showDirY == -1)
        {
            cury = height - cury;
        }

        while(datposr >= PI10000)
        {
            datposr -= (PI20000-1);
        }
        while(datposr <= -PI10000)
        {
            datposr += (PI20000-1);
        }

        dispItem.ctrl = ctrlByte;
        dispItem.attr = attrByte;
        dispItem.bx = prex;
        dispItem.by = prey;
        dispItem.ex = curx;
        dispItem.ey = cury;
        dispItem.ar = curr;

        //因坐标系不同，写画机显示时需要左转90度
        if(g_emMacType == MACHINE_DRAWING)
        {
            double bx1 = dispItem.bx;
            double by1 = dispItem.by;

            dispItem.bx = by1;
            dispItem.by = -bx1;

            if(minX > dispItem.bx)
            {
                minX = dispItem.bx;
            }
            if(minY > dispItem.by)
            {
                minY = dispItem.by;
            }
            if(maxX < dispItem.bx)
            {
                maxX = dispItem.bx;
            }
            if(maxY < dispItem.by)
            {
                maxY = dispItem.by;
            }

            double ex1 = dispItem.ex;
            double ey1 = dispItem.ey;

            dispItem.ex = ey1;
            dispItem.ey = -ex1;

            if(minX > dispItem.ex)
            {
                minX = dispItem.ex;
            }
            if(minY > dispItem.by)
            {
                minY = dispItem.by;
            }
            if(maxX < dispItem.ex)
            {
                maxX = dispItem.ex;
            }
            if(maxY < dispItem.ey)
            {
                maxY = dispItem.ey;
            }
        }
        //qDebug()<<"dispItem"<<dispItem.bx<<dispItem.by<<dispItem.ex<<dispItem.ey;

        memcpy(&dispItem.action,ds16DataPtr->action,sizeof(dispItem.action));

        dispDat.append((char*)(&dispItem), sizeof(ViewItem));

        ds16DataPtr++;
    }

    //左转90度后居中显示
    if(g_emMacType == MACHINE_DRAWING)
    {
        QByteArray dispDat1;//绘制图形的绝对数据(进行缩放的)
        dispDat1.clear();

        int size = dispDat.size() / sizeof(ViewItem);
        ViewItem* dispStep = (ViewItem*)(dispDat.data());
        double firstsx = dispStep->bx;
        double firstsy = dispStep->by;

        for(int i = 0; i < size; i++)
        {
            dispStep->bx = dispStep->bx - firstsx + dpx;
            dispStep->by = dispStep->by - firstsy + dpy;
            dispStep->ex = dispStep->ex - firstsx + dpx;
            dispStep->ey = dispStep->ey - firstsy + dpy;
            dispDat1.append((char*)(dispStep), sizeof(ViewItem));
            dispStep++;
        }

        dispDat.clear();
        dispDat.append(dispDat1);
    }

    return dispDat;
}

//设置数据区文件头的fileid，计算完以后的fileid再设置进来
void EmbData::setDsDatHeadFileID(u32 fileid)
{
    if(m_pEmbDs16Head != NULL)
    {
        m_pEmbDs16Head->fileid = fileid;
        if((u32)m_embDs16Data.size() > sizeof(DataDs16FileHead))
        {
            memcpy(m_embDs16Data.data(),(char*)m_pEmbDs16Head, sizeof(DataDs16FileHead));
        }
    }
}

//得到绝对坐标的maxXY和minXY
void EmbData::getAbsDatRangeXY()
{
    m_minX = S32_MAX;
    m_maxX = S32_MIN;
    m_minY = S32_MAX;
    m_maxY = S32_MIN;

    double ax, ay;
    int minx, miny, maxx, maxy;

    const QByteArray & ary = m_embAbsData;
    int size = ary.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
    }
    DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return;
    }
    DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;
    //-----

    int begx = pDsHead->beginX;
    int begy = pDsHead->beginY;

    minx = S32_MAX;
    maxx = S32_MIN;
    miny = S32_MAX;
    maxy = S32_MIN;

    // 数据区
    for (int j = 0; j < stepsize; j++)
    {
        ax = absDataPtr->ax + begx;
        ay = absDataPtr->ay + begy;

        //        ax = absDataPtr->ax;
        //        ay = absDataPtr->ay;

        if (minx > ax) { minx = ax; }
        if (maxx < ax) { maxx = ax; }
        if (miny > ay) { miny = ay; }
        if (maxy < ay) { maxy = ay; }

        absDataPtr++;
    }

    if (m_minX > minx) { m_minX = minx; }
    if (m_minX > maxx) { m_minX = maxx; }
    if (m_maxX < minx) { m_maxX = minx; }
    if (m_maxX < maxx) { m_maxX = maxx; }
    if (m_minY > miny) { m_minY = miny; }
    if (m_minY > maxy) { m_minY = maxy; }
    if (m_maxY < miny) { m_maxY = miny; }
    if (m_maxY < maxy) { m_maxY = maxy; }
}

// 添加锁针针步
int EmbData::addLockStitchs(u8 mode, u8 needles, u8 num)
{
    if (needles <= 0)
    {
        return -1;
    }

    int size = m_embAbsData.size();
    if (size <= 0)
    {
        return -1;
    }

    int lockNum = num;//锁针次数
    int lockNeedles = needles;//锁针针数

    QByteArray tgtdsdat;    // 添加后的绝对坐标数据
    tgtdsdat.clear();

    // 文件头
    int datasize = size - sizeof(DataDs16FileHead);
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("dat size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;

    tgtdsdat.append((char*)pHead, sizeof(DataDs16FileHead));
    //pHead = (DataDs16FileHead *)(tgtdsdat.data());

    int runflag = 0;

    for (int j = 0; j < stepsize; j++)
    {
        if (absDataPtr->ctrl == DATA_SEWING)//包括起针和剪线后加锁针
        {
            if ((runflag == 0 || runflag > 3))
            {
                // 添加锁针
                int nst = 0;

                if(mode == MODE_LOCK)//锁针方式
                {
                    if(lockNum%2 == 0)//偶数
                    {
                        nst = 1;
                    }
                    else//奇数
                    {
                        nst = needles;
                    }

                    do
                    {
                        if(j+nst < stepsize)
                        {
                            DsAbsItem * nextPtr = absDataPtr+nst;     // 要加锁针的点
                            if (nextPtr->ctrl == DATA_SEWING)
                            {
                                DsAbsItem nitem;
                                memset(&nitem,0,sizeof(DsAbsItem));

                                u8 ctrl = absDataPtr->ctrl;
                                u8 attr = 0;    // absDataPtr->attr;
                                double arbase = absDataPtr->ar;

                                if(lockNum%2 == 0)//偶数锁针
                                {
                                    nextPtr--;
                                    for (int k = 0; k < lockNum; k++)
                                    {
                                        if(k%2 == 0)
                                        {
                                            for (int s = 0; s < lockNeedles; s++)
                                            {
                                                nextPtr++;
                                                double axbase = nextPtr->ax;
                                                double aybase = nextPtr->ay;

                                                nitem.ctrl = ctrl;
                                                nitem.attr = attr;
                                                nitem.ax = axbase;
                                                nitem.ay = aybase;
                                                nitem.ar = arbase;
                                                tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
                                            }
                                        }

                                        if(k > 0 && k%2 != 0)
                                        {
                                            for (int s = lockNeedles; s > 0; s--)
                                            {
                                                nextPtr--;
                                                double axbase = nextPtr->ax;
                                                double aybase = nextPtr->ay;

                                                if(k == lockNum-1 && s == 1)
                                                {
                                                    continue;//最后一次锁针的最后一步不添加
                                                }

                                                nitem.ctrl = ctrl;
                                                nitem.attr = attr;
                                                nitem.ax = axbase;
                                                nitem.ay = aybase;
                                                nitem.ar = arbase;
                                                tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
                                            }
                                        }
                                    }
                                }
                                else//奇数锁针
                                {
                                    nextPtr++;
                                    for (int k = 0; k < lockNum; k++)
                                    {
                                        if(k%2 == 0)
                                        {
                                            for (int s = lockNeedles; s > 0; s--)
                                            {
                                                nextPtr--;
                                                double axbase = nextPtr->ax;
                                                double aybase = nextPtr->ay;

                                                if(k == 0 && s == lockNeedles)
                                                {
                                                    nitem.ctrl = DATA_OFFSET;//第一针步转换为跨步
                                                }
                                                else
                                                {
                                                    nitem.ctrl = ctrl;
                                                }

                                                nitem.attr = attr;
                                                nitem.ax = axbase;
                                                nitem.ay = aybase;
                                                nitem.ar = arbase;
                                                tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
                                            }
                                            nextPtr--;
                                        }

                                        if(k > 0 && k%2 != 0)
                                        {
                                            for (int s = 0; s < lockNeedles; s++)
                                            {
                                                double axbase = nextPtr->ax;
                                                double aybase = nextPtr->ay;

                                                nitem.ctrl = ctrl;
                                                nitem.attr = attr;
                                                nitem.ax = axbase;
                                                nitem.ay = aybase;
                                                nitem.ar = arbase;
                                                tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
                                                nextPtr++;
                                            }
                                            nextPtr++;
                                        }
                                    }
                                }
                                break;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }while(1);
                }
                else if(mode == MODE_THICKEN)//密针方式
                {
                    tgtdsdat.append((char*)absDataPtr, sizeof(DsAbsItem));

                    nst = 1;

                    s16 nNum = 0;
                    if(lockNum == 0)//如果锁针次数为0时，第一针锁针次数就是锁针针数
                    {
                        nNum = lockNeedles+1;
                    }
                    else
                    {
                        nNum = lockNum+1;
                    }

                    do
                    {
                        if(j+nst < stepsize)
                        {
                            DsAbsItem * nextPtr = absDataPtr+nst;     // 下一个点
                            if (nextPtr->ctrl == DATA_SEWING)
                            {
                                DsAbsItem nitem;
                                memset(&nitem,0,sizeof(DsAbsItem));
                                DsAbsItem * prePtr = absDataPtr;

                                u8 ctrl = absDataPtr->ctrl;
                                u8 attr = 0;    // absDataPtr->attr;
                                double arbase = absDataPtr->ar;

                                for (int s = 0; s < lockNeedles; s++)
                                {
                                    double dx = nextPtr->ax - prePtr->ax;
                                    double dy = nextPtr->ay - prePtr->ay;
                                    double len = sqrt(dx*dx + dy*dy);
                                    if (len <= 0)
                                    {
                                        prePtr = nextPtr;
                                        nextPtr++;
                                        lockNeedles++;
                                        continue;
                                    }
                                    double dLen = len / nNum;

                                    double axbase = prePtr->ax;
                                    double aybase = prePtr->ay;

                                    for (int k = 0; k < nNum; k++)
                                    {
                                        double nax = dx * dLen / len + axbase;
                                        double nay = dy * dLen / len + aybase;

                                        nitem.ctrl = ctrl;
                                        nitem.attr = attr;
                                        nitem.ax = nax;
                                        nitem.ay = nay;
                                        nitem.ar = arbase;
                                        tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));

                                        axbase = nax;
                                        aybase = nay;
                                    }
                                    if(lockNum == 0)
                                    {
                                        nNum--;
                                    }
                                    prePtr = nextPtr;
                                    nextPtr++;
                                }
                                break;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }while(1);

                    for (int s = 0; s <= lockNeedles; s++)//跳到不加锁针的那一针
                    {
                        absDataPtr++;
                        j++;
                    }
                }
                runflag = 1;
            }
        }
        else if (absDataPtr->ctrl == DATA_CUTTRD)
        {
            runflag = 10;
        }
        else
        {
            runflag = 0;
        }

        //结束前或剪线前加锁针
        if (absDataPtr->ctrl == DATA_END ||
                absDataPtr->ctrl == DATA_NULL ||
                j == stepsize-1 ||
                absDataPtr->ctrl == DATA_CUTTRD)
        {
            int m = 1;
            //结束前或剪线前加锁针
            DsAbsItem * prePtr = absDataPtr-1;     // 上一个点
            u8 ctl = prePtr->ctrl;
            while(ctl != DATA_SEWING)
            {
                prePtr--;
                m++;
                ctl = prePtr->ctrl;
                if(prePtr == pData)//起始地址
                {
                    return -1;
                }
            }

            // 添加锁针
            int nst = 1;

            if(mode == MODE_LOCK)//锁针方式
            {
                do
                {
                    if(j-m-nst > 0)
                    {
                        DsAbsItem * lockPtr = prePtr;     // 要加锁针的点
                        if (lockPtr->ctrl == DATA_SEWING)
                        {
                            DsAbsItem nitem;
                            memset(&nitem,0,sizeof(DsAbsItem));

                            u8 ctrl = prePtr->ctrl;
                            u8 attr = 0;    // absDataPtr->attr;
                            double arbase = prePtr->ar;

                            for (int k = 0; k < lockNum; k++)
                            {
                                if(k%2 == 0)
                                {
                                    for (int s = lockNeedles; s > 0; s--)
                                    {
                                        lockPtr--;
                                        double axbase = lockPtr->ax;
                                        double aybase = lockPtr->ay;

                                        nitem.ctrl = ctrl;
                                        nitem.attr = attr;
                                        nitem.ax = axbase;
                                        nitem.ay = aybase;
                                        nitem.ar = arbase;
                                        tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
                                    }
                                }

                                if(k > 0 && k%2 != 0)
                                {
                                    for (int s = 0; s < lockNeedles; s++)
                                    {
                                        lockPtr++;
                                        double axbase = lockPtr->ax;
                                        double aybase = lockPtr->ay;

                                        nitem.ctrl = ctrl;
                                        nitem.attr = attr;
                                        nitem.ax = axbase;
                                        nitem.ay = aybase;
                                        nitem.ar = arbase;
                                        tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));
                                    }
                                }
                            }
                            break;
                        }
                        else
                        {
                            break;
                        }
                    }
                }while(1);
            }
            else if(mode == MODE_THICKEN)//密针方式
            {
                nst = needles;
                //去除要加密针的已添加的针步
                tgtdsdat.remove(tgtdsdat.size()-needles*sizeof(DsAbsItem),needles*sizeof(DsAbsItem));

                s16 nNum = 0;
                if(lockNum == 0)//如果锁针次数为0时，第一针锁针次数就是锁针针数
                {
                    nNum = lockNeedles+1;
                }
                else
                {
                    nNum = lockNum+1;
                }

                do
                {
                    if(j-m-nst > 0)
                    {
                        DsAbsItem * lockPtr = prePtr-lockNeedles;     // 加锁针点
                        if (lockPtr->ctrl == DATA_SEWING)
                        {
                            DsAbsItem nitem;
                            memset(&nitem,0,sizeof(DsAbsItem));

                            u8 ctrl = prePtr->ctrl;
                            u8 attr = 0;    // absDataPtr->attr;
                            double arbase = prePtr->ar;

                            for (int s = 0; s < lockNeedles; s++)
                            {
                                DsAbsItem * nextPtr = lockPtr+1;
                                double dx = nextPtr->ax - lockPtr->ax;
                                double dy = nextPtr->ay - lockPtr->ay;
                                double len = sqrt(dx*dx + dy*dy);
                                if (len <= 0)
                                {
                                    if(lockNum == 0)
                                    {
                                        nNum--;
                                    }

                                    lockPtr++;
                                    continue;
                                }
                                double dLen = len / nNum;

                                double axbase = lockPtr->ax;
                                double aybase = lockPtr->ay;

                                for (int k = 0; k < nNum; k++)
                                {
                                    double nax = dx * dLen / len + axbase;
                                    double nay = dy * dLen / len + aybase;

                                    nitem.ctrl = ctrl;
                                    nitem.attr = attr;
                                    nitem.ax = nax;
                                    nitem.ay = nay;
                                    nitem.ar = arbase;
                                    tgtdsdat.append((char*)(&nitem), sizeof(DsAbsItem));

                                    axbase = nax;
                                    aybase = nay;
                                }
                                if(lockNum == 0)
                                {
                                    nNum--;
                                }
                                lockPtr++;
                            }
                            break;
                        }
                        else
                        {
                            break;
                        }
                    }
                }while(1);
            }
        }

        tgtdsdat.append((char*)absDataPtr, sizeof(DsAbsItem));

        absDataPtr++;
    }

    m_embAbsData.clear();
    m_embAbsData = tgtdsdat;

    m_editedflag = 1;
    return 0;
}

//角度修正
int EmbData::angleCorrectionBak(s16 oft)
{
    if (oft != 0)
    {
        s32 dx, dy, dr;
        double ax, ay, ar;
        int bdx, bdy;
        bdx = bdy = 0;

        int size = m_embAbsData.size();
        if (size <= (int)sizeof(DataDs16FileHead))
        {
            qDebug("ary data less then head size");
            return -1;
        }

        int datasize = size - sizeof(DataDs16FileHead);
        if (datasize <= 0)
        {
            qDebug("absdat dataBegin err");
            return -1;
        }
        int stepsize = datasize/sizeof(DsAbsItem);
        if (stepsize <= 0)
        {
            qDebug("absdat data size err");
            return -1;
        }
        DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
        DsAbsItem * absDataPtr = pData;  //中间数据针步

        DsAbsItem * tempPtr;
        DsAbsItem * secondPtr;//第二个点坐标指针

        double addx,addy;
        addx = addy = 0;
        double s = 0;

        int firstY = 0;//花样第一点坐标

        // 数据区
        for (int j = 0; j < stepsize; j++)
        {
            if (j == 0)//第一针
            {
                dx = absDataPtr->ax;
                dy = absDataPtr->ay;
                dr = absDataPtr->ar;
                firstY = absDataPtr->ay;
            }
            else
            {
                dx = absDataPtr->ax - ax;
                dy = absDataPtr->ay - ay;
                dr = absDataPtr->ar - ar;
            }

            if (j == 1)//第二针
            {
                secondPtr = absDataPtr;
            }

            //判断夹角是否大于60度
            if(dr >= ANGLECORR || dr <= -ANGLECORR || j == stepsize - 1)
            {
                s = sqrt(bdx*bdx + bdy*bdy);
                if(s == 0)
                {
                    addx = 0;
                    addy = 0;
                }
                else
                {
                    addx = bdx*oft/s;
                    addy = bdy*oft/s;
                    m_endPosX = addx;
                    m_endPosY = addy;
                }

                absDataPtr--;
                if(absDataPtr->ctrl == DATA_SEWING)
                {
                    absDataPtr->ax += addx;
                    absDataPtr->ay += addy;
                    tempPtr = absDataPtr-1;
                    int oftVal = 0;
                    while(tempPtr != pData && abs(tempPtr->ar - absDataPtr->ar) <= 10000*PI/180.0)
                    {
                        tempPtr--;
                        oftVal++;
                    }

                    if(oftVal != 0)
                    {
                        tempPtr++;
                    }

                    for(int m = 0; m < oftVal; m++)
                    {
                        tempPtr->ax += (m+1)*addx/oftVal;
                        tempPtr->ay += (m+1)*addy/oftVal;
                        tempPtr++;
                    }
                }
                absDataPtr++;
            }

            ax = absDataPtr->ax;
            ay = absDataPtr->ay;
            ar = absDataPtr->ar;

            bdx = dx;
            bdy = dy;

            absDataPtr++;
        }

        DsAbsItem *datItem = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead)+sizeof(DsAbsItem)*(stepsize-1));

        DsAbsItem insertItem;
        memcpy(&insertItem,datItem,sizeof(DsAbsItem));

        int mdy = (secondPtr->ay) - firstY;
        double modY = (datItem->ay) + mdy;

        insertItem.ctrl = DATA_SEWING;
        double tar = atan2((modY-datItem->ay),(secondPtr->ax-datItem->ax));
        insertItem.ar = (tar * 10000+0.5*(tar>0?1:-1));
        insertItem.ax = secondPtr->ax;
        insertItem.ay = modY;
        m_embAbsData.insert(sizeof(DataDs16FileHead)+sizeof(DsAbsItem)*(stepsize-1),(char*)(&insertItem),sizeof(DsAbsItem));//插入回针
        m_embAbsData.remove(sizeof(DataDs16FileHead),sizeof(DsAbsItem));//去掉第一针
    }
    return 0;
}

//拐角" x/y+-"补偿老版本
int EmbData::angleCorrectionXYBack(s32 px, s32 nx, s32 py, s32 ny)
{
    if(px == 0 && nx == 0 && py == 0 && ny == 0)
    {
        return -1;
    }
    s32 dx, dy, dr;
    double ax, ay, ar;

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步

    double addx,addy;
    addx = addy = 0;

    // 数据区
    for (int j = 0; j < stepsize; j++)
    {
        if (j == 0)//第一针
        {
            dx = absDataPtr->ax;
            dy = absDataPtr->ay;
            dr = absDataPtr->ar;
        }
        else
        {
            dx = absDataPtr->ax - ax;
            dy = absDataPtr->ay - ay;
            dr = absDataPtr->ar - ar;
        }

        //判断夹角是否大于60度
        if(dr >= ANGLECORR || dr <= -ANGLECORR)
        {
            if(dx > 0)
            {
                addx = px;
            }
            else if(dx == 0)
            {
                DsAbsItem * prePtr = absDataPtr-1;
                double prex = prePtr ->ax;
                while(prex == absDataPtr->ax)
                {
                    prePtr--;
                    prex = prePtr->ax;
                    if(prePtr == pData)
                    {
                        break;
                    }
                }
                s32 cx = prex - absDataPtr->ax;
                if(cx < 0)
                {
                    addx = px;
                }
                else
                {
                    addx = 0 - nx;
                }
            }
            else
            {
                addx = 0 - nx;
            }

            if(dy > 0)
            {
                addy = py;
            }
            else if(dy == 0)
            {
                DsAbsItem * prePtr = absDataPtr-1;
                double prey = prePtr ->ay;
                while(prey == absDataPtr->ay)
                {
                    prePtr--;
                    prey = prePtr->ay;
                    if(prePtr == pData)
                    {
                        break;
                    }
                }
                s32 cy = prey - absDataPtr->ay;
                if(cy < 0)
                {
                    addy = py;
                }
                else
                {
                    addy = 0 - ny;
                }
            }
            else
            {
                addy = 0 - ny;
            }

            absDataPtr--;
            if(absDataPtr->ctrl == DATA_SEWING)
            {
                absDataPtr->ax += addx;
                absDataPtr->ay += addy;
            }
            absDataPtr++;
        }

        ax = absDataPtr->ax;
        ay = absDataPtr->ay;
        ar = absDataPtr->ar;

        absDataPtr++;
    }

    return 0;
}

//按固定针步重新拟合（用户可设置的参数，暂未用到）
void EmbData::reFitByStep(s32 stepLen)
{
    QList<LineItem> lineList;
    lineList.clear();

    int stepLength = stepLen;//参数(300-800 单位0.01mm)

    LineItem item;
    item.absItemList.clear();

    int dr = 0;
    unsigned char ctrl;
    double prer = 0;

    double ax, ay, ar;
    ax = ay = ar = 0;

    DsAbsItem absItem;
    memset(&absItem,0,sizeof(DsAbsItem));

    //添加线段集合（夹角大于某个值时为新的一段线段）
    int datasize = m_embAbsData.size() - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        return;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    DsAbsItem * dataBeg = (DsAbsItem *)(m_embAbsData.data()+sizeof(DataDs16FileHead));
    prer = dataBeg->ar;
    for (int i = 0; i < stepsize; i++)
    {
        ctrl = dataBeg->ctrl;
        dr = dataBeg->ar - prer;

        unsigned char nctrl,bctrl;
        if(i == stepsize-1)
        {
            nctrl = ctrl;
        }
        else
        {
            dataBeg++;
            nctrl = dataBeg->ctrl;//下一针步属性
            dataBeg--;
        }

        if(i == 0)
        {
            bctrl = ctrl;
        }
        else
        {
            dataBeg--;
            bctrl = dataBeg->ctrl;//上一针步属性
            dataBeg++;
        }

        if(ctrl != DATA_SEWING)
        {
            item.absItemList.append(*dataBeg);
        }

        //上一针非缝纫属性且当前针为缝纫属性
        if(bctrl != DATA_SEWING && ctrl == DATA_SEWING)
        {
            lineList.append(item);
            item.absItemList.clear();
            item.absItemList.append(*dataBeg);
        }
        //下一针非缝纫针步与当前针为缝纫针步
        else if(nctrl != DATA_SEWING && ctrl == DATA_SEWING)
        {
            lineList.append(item);
            item.absItemList.clear();
            item.absItemList.append(*dataBeg);
        }
        //上一针为缝纫针步与当前针非缝纫针步
        else if(bctrl == DATA_SEWING && ctrl != DATA_SEWING)
        {
            lineList.append(item);
            item.absItemList.clear();
            item.absItemList.append(*dataBeg);
        }
        //下一针为缝纫针步与当前针非缝纫针步
        else if(nctrl == DATA_SEWING && ctrl != DATA_SEWING)
        {
            lineList.append(item);
            item.absItemList.clear();
            item.absItemList.append(*dataBeg);
        }
        else if(ctrl == DATA_SEWING)
        {
            double angle = dr / 10000.0 * (180.0 / PI);
            if(angle > 30 || angle < -30)//新的一条线段(30度为分界)
            {
                lineList.append(item);
                item.absItemList.clear();
                item.absItemList.append(*dataBeg);
            }
            else
            {
                item.absItemList.append(*dataBeg);
            }
        }
        prer = dataBeg->ar;
        dataBeg++;
    }

    //开始重置针步（绝对坐标的线段集合）
    QByteArray nabsData;
    nabsData.clear();
    double cx,cy,cr;
    cx = cy = cr = 0;
    int lSize = lineList.size();
    for(int j = 0; j < lSize; j++)
    {
        int pSize = lineList[j].absItemList.size();
        for(int m = 0; m < pSize; m++)
        {
            memset(&absItem,0,sizeof(DsAbsItem));
            absItem = lineList[j].absItemList[m];

            ctrl = absItem.ctrl;
            //absItem.ax = absItem.ax - minX;
            //absItem.ay = absItem.ay - minY;
            ax = absItem.ax;
            ay = absItem.ay;
            ar = absItem.ar;

            if(ctrl != DATA_SEWING)
            {
                nabsData.append((char*)&absItem,sizeof(DsAbsItem));
                continue;
            }
            if(m == 0)
            {
                cx = ax;
                cy = ay;
                nabsData.append((char*)&absItem,sizeof(DsAbsItem));
            }
            if(m == pSize - 1 && pSize > 1)
            {
                //最后一步如果超出长度就均分
                int pos = nabsData.size()-sizeof(DsAbsItem);
                DsAbsItem * litem = (DsAbsItem *)((nabsData.data()+pos));

                double curX = absItem.ax;
                double curY = absItem.ay;

                double preX = litem->ax;
                double preY = litem->ay;

                double ldis = sqrt(((curX-preX)/100.0*(curX-preX)/100.0)*10000.0+((curY-preY)/100.0*(curY-preY)/100.0)*10000.0);
                if(ldis > stepLength)
                {
                    DsAbsItem addItem;
                    memset(&addItem,0,sizeof(DsAbsItem));
                    addItem = absItem;

                    if(litem->ay == absItem.ay)//y相同
                    {
                        addItem.ay = absItem.ay;
                        addItem.ax = (absItem.ax+litem->ax)/2;

                        nabsData.append((char*)&addItem,sizeof(DsAbsItem));
                        nabsData.append((char*)&absItem,sizeof(DsAbsItem));
                        break;
                    }
                    else if(litem->ax == absItem.ax)//x相同
                    {
                        addItem.ax = absItem.ax;
                        addItem.ay = (absItem.ay+litem->ay)/2;

                        nabsData.append((char*)&addItem,sizeof(DsAbsItem));
                        nabsData.append((char*)&absItem,sizeof(DsAbsItem));
                        break;
                    }
                    else
                    {
                        double k = ((double)(absItem.ay-litem->ay))/((double)(absItem.ax-litem->ay));
                        double cdis = ldis / 2;
                        double r = atan(k);
                        double x = cdis * cos(r);
                        double y = cdis * sin(r);

                        addItem.ax = litem->ax + x;
                        addItem.ay = litem->ay + y;
                        nabsData.append((char*)&addItem,sizeof(DsAbsItem));

                        nabsData.append((char*)&absItem,sizeof(DsAbsItem));
                        break;
                    }
                }
                else
                {
                    nabsData.append((char*)&absItem,sizeof(DsAbsItem));
                    break;
                }
            }
            double dis = sqrt(((ax-cx)/100.0*(ax-cx)/100.0)*10000.0+((ay-cy)/100.0*(ay-cy)/100.0)*10000.0);
            while(dis > stepLength)
            {
                QPoint firstPoint(0,0);//直线第一个点
                if((m-1) >= 0)
                {
                    //                    firstPoint.setX(lineList[j].absItemList[m-1].ax-minX);
                    //                    firstPoint.setY(lineList[j].absItemList[m-1].ay-minY);
                    firstPoint.setX(lineList[j].absItemList[m-1].ax);
                    firstPoint.setY(lineList[j].absItemList[m-1].ay);
                }

                QPoint secondPoint;//直线第二个点
                secondPoint.setX(ax);
                secondPoint.setY(ay);

                QPoint circlePoint;//圆心
                circlePoint.setX(cx);
                circlePoint.setY(cy);

                QPoint p;
                if(secondPoint.x()-firstPoint.x() == 0)
                {
                    p.setX(secondPoint.x());
                    //int y = (secondPoint.y()/stepLength)*stepLength;
                    //int y = (secondPoint.y()+firstPoint.y())/2;
                    //取出上一点的坐标
                    int pos = nabsData.size()-sizeof(DsAbsItem);
                    DsAbsItem * litem = (DsAbsItem *)((nabsData.data()+pos));
                    int y = 0;
                    if(litem->ay >= secondPoint.y())
                    {
                        y = litem->ay - stepLength;
                    }
                    else
                    {
                        y = litem->ay + stepLength;
                    }

                    p.setY(y);

                    cx = p.x();
                    cy = p.y();

                    if(cx < 0 || cy < 0)
                    {
                        //qDebug()<<j<<m<<cx<<cy;
                    }

                    absItem.ax = cx;
                    absItem.ay = cy;
                    nabsData.append((char*)&absItem,sizeof(DsAbsItem));

                    dis = sqrt(((ax-cx)/100.0*(ax-cx)/100.0)*10000.0+((ay-cy)/100.0*(ay-cy)/100.0)*10000.0);
                }
                else
                {
                    //(x - cx )^2 + (y - cy)^2 = r^2
                    //y = kx +b

                    // 求得直线方程
                    double k = ((double)(secondPoint.y()-firstPoint.y()))/(secondPoint.x()-firstPoint.x());
                    double b = firstPoint.y()-k*firstPoint.x();

                    // 列方程
                    //(1 + k^2)*x^2 - x*(2*cx -2*k*(b -cy) ) + cx*cx + ( b - cy)*(b - cy) - r*r = 0

                    int x1,y1,x2,y2;
                    double c = (circlePoint.x()/100.0)*(circlePoint.x()/100.0)*10000.0+((b-circlePoint.y())/100.0)*((b-circlePoint.y())/100.0)*10000.0-stepLength*stepLength;
                    double a = (1+k*k);
                    double b1 = 2*circlePoint.x()-2*k*(b-circlePoint.y());
                    // 得到下面的简化方程
                    // a*x^2 - b1*x + c = 0;

                    double sval = (b1/100.0)*(b1/100.0)*10000.0-4*a*c;
                    if(sval < 0)
                    {
                        qDebug()<<j<<sval;
                        //sval = abs(sval);
                    }
                    double tmp = sqrt(sval);
                    x1 = qRound((b1+tmp)/(2*a));
                    y1 = qRound(k*x1+b);
                    x2 = qRound((b1-tmp)/(2*a));
                    y2 = qRound(k*x2+b);

                    //判断点是否在第一个和第二个点之间
                    QPoint p1(x1,y1);
                    QPoint p2(x2,y2);

                    QRect rect(firstPoint,secondPoint);
                    bool bl1 = false;
                    if(rect.contains(p1))
                    {
                        bl1 = true;
                    }

                    bool bl2 = false;
                    if(rect.contains(p2))
                    {
                        bl2 = true;
                    }

                    // 判断求出的点是否在圆上
                    int res = qRound(sqrt((x1-cx)*(x1-cx)+(y1-cy)*(y1-cy)));
                    bool bl3 = true;//这里让此条件一直成立
                    if(res <= (stepLength+10) &&
                            res >= (stepLength-10))
                    {
                        bl3 = true;
                    }

                    if(bl3)
                    {
                        if(bl1 == true && bl2 == true)
                        {
                            double dis1 = sqrt(((ax-x1)/100.0*(ax-x1)/100.0)*10000.0+((ay-y1)/100.0*(ay-y1)/100.0)*10000.0);
                            double dis2 = sqrt(((ax-x2)/100.0*(ax-x2)/100.0)*10000.0+((ay-y2)/100.0*(ay-y2)/100.0)*10000.0);
                            if(dis1 > dis2)
                            {
                                cx = x2;
                                cy = y2;
                            }
                            else
                            {
                                cx = x1;
                                cy = y1;
                            }

                            absItem.ax = cx;
                            absItem.ay = cy;
                            nabsData.append((char*)&absItem,sizeof(DsAbsItem));

                            dis = sqrt(((ax-cx)/100.0*(ax-cx)/100.0)*10000.0+((ay-cy)/100.0*(ay-cy)/100.0)*10000.0);
                        }
                        else
                        {
                            if(bl1)
                            {
                                p.setX(x1);
                                p.setY(y1);
                            }
                            else if(bl2)
                            {
                                p.setX(x2);
                                p.setY(y2);
                            }
                            else
                            {
                                qDebug()<<"bl1&bl2=false";
                                break;
                            }

                            cx = p.x();
                            cy = p.y();

                            if(cx < 0 || cy < 0)
                            {
                                //qDebug()<<j<<m<<cx<<cy;
                            }

                            absItem.ax = cx;
                            absItem.ay = cy;
                            nabsData.append((char*)&absItem,sizeof(DsAbsItem));

                            dis = sqrt(((ax-cx)/100.0*(ax-cx)/100.0)*10000.0+((ay-cy)/100.0*(ay-cy)/100.0)*10000.0);
                        }
                    }
                    else
                    {
                        qDebug()<<"bl3=false";
                        break;
                    }
                }
            }
        }
    }

    //修改绝对坐标数据
    stepsize = nabsData.size() / sizeof(DsAbsItem);

    m_pEmbDs16Head->dataSize = stepsize*sizeof(DsAbsItem);    // 数据字节数
    m_pEmbDs16Head->itemNums = stepsize;                    // 数据项个数
    m_pEmbDs16Head->dataChecksum = calcCheckSum32((u8 *)(nabsData.data()) , nabsData.length());		// 数据累加校验和
    m_pEmbDs16Head->checkCrc = calcCrc16((u8 *)(m_pEmbDs16Head), HEAD_FIX_INFO_LEN);	// 前面6个字段的CRC校验，（6个字段分别为：文件名称，字节数，项个数，每项字节数，每块字节数，数据累加和的CRC校验值）
    u32 fileID = 0;
    fileID = calcCheckSum32((u8 *)(nabsData.data()) , nabsData.length());		// 原始数据累加校验和
    m_pEmbDs16Head->fileid = fileID;  //中间数据的 fileid  =

    m_embAbsData.clear();
    m_embAbsData.append((char *)(m_pEmbDs16Head), sizeof(DataDs16FileHead));
    m_embAbsData.append(nabsData);
}

#define MERGEANGLE      PI/180*70*10000 //70度
void EmbData::reFitLine(s32 stepLen)
{
    QList<LineItem> lineList;
    lineList.clear();

    double stepLength = stepLen;//参数(200-800 单位0.01mm)
    if(stepLength <= 0)
    {
        return;
    }

    LineItem item;
    item.absItemList.clear();

    int dr = 0;
    double prer = 0;
    DsAbsItem preItem;
    memset(&preItem,0,sizeof(DsAbsItem));
    s16 addOftFlag = 0;
    s16 addSewFlag = 0;

    DsAbsItem absItem;
    memset(&absItem,0,sizeof(DsAbsItem));

    //添加线段集合（夹角大于某个值时为新的一段线段）
    int datasize = m_embAbsData.size() - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        return;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    memcpy((char*)m_pEmbDs16Head,m_embAbsData.data(),sizeof(DataDs16FileHead));
    DsAbsItem * dataBeg = (DsAbsItem *)(m_embAbsData.data()+sizeof(DataDs16FileHead));
    prer = dataBeg->ar;
    for (int i = 0; i < stepsize; i++)
    {
        dr = dataBeg->ar - prer;

        while (dr < -PI10000)
        {
            dr += PI20000;
        }
        while (dr > PI10000)
        {
            dr -= PI20000;
        }

        if(dataBeg->ctrl != DATA_SEWING)
        {
            if(addSewFlag == 1)
            {
                lineList.append(item);
                item.absItemList.clear();
                item.absItemList.append(*(dataBeg-1));
                addSewFlag = 0;
            }
            item.absItemList.append(*dataBeg);
            addOftFlag = 1;
        }
        else
        {
            addSewFlag = 1;
            if(addOftFlag == 1)
            {
                lineList.append(item);
                item.absItemList.clear();
                item.absItemList.append(*(dataBeg-1));
                item.absItemList.append(*dataBeg);
                addOftFlag = 0;
            }
            if((abs(dr) > MERGEANGLE))//新的一条线段
            {
                lineList.append(item);
                item.absItemList.clear();
                item.absItemList.append(*(dataBeg-1));
                item.absItemList.append(*dataBeg);
            }
            else
            {
                item.absItemList.append(*dataBeg);
            }
        }

        prer = dataBeg->ar;
        dataBeg++;
    }

    //开始重置针步（绝对坐标的线段集合）
    QByteArray nabsData;
    nabsData.clear();
    QList<DsAbsItem> outList;

    int lSize = lineList.size();
    for(int i = 0; i < lSize; i++)
    {
        outList.clear();

        int pSize = lineList[i].absItemList.size();
        if(pSize == 1)//只有一个点
        {
            nabsData.append((char*)&lineList[i].absItemList[0],sizeof(DsAbsItem));
        }
        else
        {
            getCurvePointFillLine(lineList[i].absItemList,stepLength,outList);
            //从第二段开始起始点不向绝对坐标中添加，如果添加会出现空针步
            int idx = 0;
            if(i > 0)
            {
                idx = 1;
            }
            for(int m = idx; m < outList.size(); m++)
            {
                nabsData.append((char*)(&outList[m]), sizeof(DsAbsItem));
            }
        }
    }

    //重新计算ar
    stepsize = nabsData.size() / sizeof(DsAbsItem);
    if(stepsize <= 0)
    {
        return;
    }

    //最后添加结束码，ax和ay是最后一针的
    DsAbsItem dsAbsItem;
    memcpy(&dsAbsItem,nabsData.data()+(nabsData.size() - sizeof(DsAbsItem)),sizeof(DsAbsItem));
    dsAbsItem.ctrl = DATA_END;
    nabsData.append((char*)(&dsAbsItem), sizeof(DsAbsItem));
    stepsize++;

    DsAbsItem * absDataPtr = (DsAbsItem *)(nabsData.data());

    double minX, maxX, minY, maxY;
    minX = S32_MAX;
    maxX = S32_MIN;
    minY = S32_MAX;
    maxY = S32_MIN;

    double prex,prey,curx,cury,dx,dy,ar;
    prex = prey = curx = cury = dx = dy = ar = 0;

    prex = absDataPtr->ax;
    prey = absDataPtr->ay;

    for (int i = 0; i < stepsize; i++)
    {
        curx = absDataPtr->ax;
        cury = absDataPtr->ay;

        dx = curx - prex;
        dy = cury - prey;

        double tar = atan2(dy,dx);
        ar = (tar*10000+0.5*(tar>0?1:-1));
        absDataPtr->ar = ar;

        if(curx > maxX)
        {
            maxX = curx;
        }
        if(curx < minX)
        {
            minX = curx;
        }

        if(cury > maxY)
        {
            maxY = cury;
        }
        if(cury < minY)
        {
            minY = cury;
        }

        prex = curx;
        prey = cury;

        absDataPtr++;
    }

    //修改绝对坐标数据
    m_pEmbDs16Head->dataSize = stepsize*sizeof(DsAbsItem);    // 数据字节数
    m_pEmbDs16Head->itemNums = stepsize;                    // 数据项个数
    m_pEmbDs16Head->maxX = maxX;
    m_pEmbDs16Head->minX = minX;
    m_pEmbDs16Head->maxY = maxY;
    m_pEmbDs16Head->minY = minY;
    m_pEmbDs16Head->dataChecksum = calcCheckSum32((u8 *)(nabsData.data()) , nabsData.length());		// 数据累加校验和
    m_pEmbDs16Head->checkCrc = calcCrc16((u8 *)(m_pEmbDs16Head), HEAD_FIX_INFO_LEN);	// 前面6个字段的CRC校验，（6个字段分别为：文件名称，字节数，项个数，每项字节数，每块字节数，数据累加和的CRC校验值）
    u32 fileID = 0;
    fileID = calcCheckSum32((u8 *)(nabsData.data()) , nabsData.length());		// 原始数据累加校验和
    m_pEmbDs16Head->fileid = fileID;  //中间数据的 fileid  =

    m_embAbsData.clear();
    m_embAbsData.append((char *)(m_pEmbDs16Head), sizeof(DataDs16FileHead));
    m_embAbsData.append(nabsData);
}

//移动起始点，左边，前边
int EmbData::moveStartPoint(short left, short front)
{
    if(m_pEmbDs16Head == NULL){return -1;}
    if(m_embDs16Data.size() <= 0){return -1;}

    m_pEmbDs16Head->anchorX += left;
    m_pEmbDs16Head->anchorY += front;
    m_pEmbDs16Head->beginX += left;
    m_pEmbDs16Head->beginY += front;

    //将最大最小值写入文件头
    m_pEmbDs16Head->maxX += left;
    m_pEmbDs16Head->minX += left;
    m_pEmbDs16Head->maxY += front;
    m_pEmbDs16Head->minY += front;

    m_maxX += left;
    m_minX += left;
    m_maxY += front;
    m_minY += front;
    memcpy(m_embDs16Data.data(),(char*)m_pEmbDs16Head,sizeof(DataDs16FileHead));

    return 0;
}

void EmbData::moveDataBeginPonit(s32 left, s32 front)
{
    if((u32)m_embAbsData.size() > sizeof(DataDs16FileHead)){
        DataDs16FileHead *dhead = (DataDs16FileHead *)(m_embAbsData.data());
        dhead->beginX += left;
        dhead->beginY += front;
        dhead->maxX += left;
        dhead->minX += left;
        dhead->maxY += front;
        dhead->minY += front;
    }
}

void EmbData::appendAEmbAbsFile(QString filePath, QByteArray array, int mirror)
{
    m_filePath = filePath;
    convertAbsDat(array,mirror);//是否镜像、旋转、缩放的转换
    m_embAbsData.clear();
    m_embAbsData.append(array);
    m_editedflag = 1;
}

void EmbData::setAbsDat(QByteArray & dat)
{
    m_embAbsData = dat;
}

QByteArray &  EmbData::getAbsDat(void)
{
    return m_embAbsData;
}

int EmbData::getPosInfoFromNeedleIdx(int stitchIdx, int &posx, int &posy, int &colorIdx)
{
    if (m_editedflag != 0)
    {
        createEmbDs16FromAbs();
    }

    posx = 0;
    posy = 0;
    colorIdx = 0;

    // 文件头
    int size = m_embDs16Data.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("m_embDs16Data data less then head size");
        return -1;
    }

    DataDs16FileHead * pDsHead = (DataDs16FileHead *)(m_embDs16Data.data());

    int datasize = size - sizeof(DataDs16FileHead);
    int stepsize = datasize/sizeof(Ds16Item);
    if (stepsize <= 0)
    {
        qDebug("ds16 data size err");
        return -1;
    }

    Ds16Item * ds16DataPtr;
    Ds16Item * pData = (Ds16Item *)(m_embDs16Data.data() + sizeof(DataDs16FileHead));
    ds16DataPtr = pData;

    posx = pDsHead->beginX;
    posy = pDsHead->beginY;

    colorIdx = 1;

    if (stitchIdx <= 0)
    {
        return 0;
    }

    if (stitchIdx > datasize)
    {
        stitchIdx = datasize;
    }

    int dx, dy;
    u8 ctrl, attr;

    for (int i = 0; i < stitchIdx; i++)
    {
        ctrl = ds16DataPtr->ctrl;
        attr = ds16DataPtr->attr;
        dx = ds16DataPtr->dx;
        dy = ds16DataPtr->dy;

        if (ctrl == DATA_CHGND)
        {
            colorIdx++;
        }

        if ((attr&0x80) != 0)
        {
            dx *= -1;
        }

        if ((attr&0x40) != 0)
        {
            dy *= -1;
        }

        posx += dx;
        posy += dy;

        ds16DataPtr++;
    }

    return 0;
}

//设置起始点
void EmbData::setStartPosition(int x, int y)
{
    qDebug()<<__FUNCTION__;
    if(m_pEmbDs16Head == NULL){
        qDebug()<< "(m_pEmbDs16Head == NULL)";
        return;
    }
    if(m_embDs16Data.size() <= 0){
        qDebug()<< "(m_embDs16Data.size() <= 0)";
        return;
    }


    if(g_emMacType == MACHINE_FLYFLATCUTTING)
    {// 飞行切割机对定位点,做特殊处理    coco
        int headX =  x + (m_pEmbDs16Head->maxX - m_pEmbDs16Head->beginX);   // 反推出 机头坐标X
        int headY =  y + (m_pEmbDs16Head->maxY - m_pEmbDs16Head->beginY);   // 反推出 机头坐标Y

        s32 cx = headX - m_pEmbDs16Head->minX;// X偏移量
        s32 cy = headY - m_pEmbDs16Head->minY;// Y偏移量

        //        s32 bx = m_pEmbDs16Head->beginX - m_pEmbDs16Head->minX; // 起始点偏差
        //        s32 by = m_pEmbDs16Head->beginY - m_pEmbDs16Head->minY;

        //        s32 weight = m_pEmbDs16Head->maxX - m_pEmbDs16Head->minX;// 宽
        //        s32 height = m_pEmbDs16Head->maxY - m_pEmbDs16Head->minY;// 高

        m_pEmbDs16Head->minX += cx;
        m_pEmbDs16Head->minY += cy;

        m_pEmbDs16Head->beginX += cx;
        m_pEmbDs16Head->beginY += cy;

        m_pEmbDs16Head->maxX += cx;
        m_pEmbDs16Head->maxY += cy;

    }
    else
    {
        //旧的起始点坐标
        int oldBeginX = m_pEmbDs16Head->beginX;
        int oldBeginY = m_pEmbDs16Head->beginY;

        m_pEmbDs16Head->beginX = x;
        m_pEmbDs16Head->beginY = y;

        //新的起始点坐标与旧的起始点坐标的差值
        int cx =  x - oldBeginX;
        int cy =  y - oldBeginY;

        //重新计算最大最小XY
        double maxX = m_pEmbDs16Head->maxX + cx;
        double minX = m_pEmbDs16Head->minX + cx;
        double maxY = m_pEmbDs16Head->maxY + cy;
        double minY = m_pEmbDs16Head->minY + cy;

        //将最大最小值写入文件头
        m_pEmbDs16Head->maxX = maxX;
        m_pEmbDs16Head->minX = minX;
        m_pEmbDs16Head->maxY = maxY;
        m_pEmbDs16Head->minY = minY;

        //修复偶尔点击中间按钮花样消失的bug
        m_maxX = maxX;
        m_minX = minX;
        m_maxY = maxY;
        m_minY = minY;
    }

    memcpy(m_embDs16Data.data(),(char*)m_pEmbDs16Head,sizeof(DataDs16FileHead));
    qDebug()<<"m_maxX"<<m_maxX<<"m_minX"<<m_minX;
    qDebug()<<"m_maxY"<<m_maxY<<"m_minY"<<m_minY;
    qDebug()<<"beginx"<<x<<"beginy"<<y;

#if(0)
    QString suffix = ".ds16";
    QString dsFilePath = m_filePath + suffix;
    QFile file(dsFilePath);

    if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
    {
        qDebug() << "open file fail when wirte, path =" << m_filePath;
        return;
    }
    else
    {
        file.write(m_embDs16Data);
        file.close();
    }
#endif
}

void EmbData::setAnchorPosition(int x, int y)
{
    if(m_pEmbDs16Head == NULL){return;}
    if(m_embDs16Data.size() <= 0){return;}

    m_pEmbDs16Head->anchorX = x;
    m_pEmbDs16Head->anchorY = y;

    memcpy(m_embDs16Data.data(),(char*)m_pEmbDs16Head,sizeof(DataDs16FileHead));

#if(0)
    QString suffix = ".ds16";
    QString dsFilePath = m_filePath + suffix;
    QFile file(dsFilePath);

    if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
    {
        qDebug() << "open file fail when wirte, path =" << m_filePath;
        return;
    }
    else
    {
        file.write(m_embDs16Data);
        file.close();
    }
#endif
}

double EmbData::getAngle(double x1, double y1, double x2, double y2)
{
    double angle;
    if(x1 == x2)
    {
        if(y2 > y1)
        {
            angle = 90.0;
        }
        else
        {
            angle = 270.0;
        }
    }
    else if (y1 == y2)
    {
        if(x1 > x2)
        {
            angle = 180.0;
        }
        else
        {
            angle = 0.0;
        }
    }
    else
    {
        angle = atan((y2 - y1)*1.0 / (x2 - x1) *1.0)*180/M_PI;

        if(angle < 0)
        {
            if(x1 > x2)
            {
                angle = angle + 180.0;
            }
            else
            {
                angle = angle + 360.0;
            }
        }
        else
        {
            if(x1 > x2)
            {
                angle = angle + 180.0;
            }
        }
    }

    return angle;
}

int EmbData::setDatSizeChange(int dsx, int dsy)
{
    //因为帽绣机要有100%以下的缩放倍率，所以将  dsx <= 0 && dsy <= 0，改为以下 -rq
    if (dsx <= 0 && dsy <= 0)
    {
        return 0;
    }

    // 文件头
    const QByteArray & ary = m_embAbsData;
    int size = ary.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("dat data size err");
        return -1;
    }

    DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());

    DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;

    int  width  = m_maxX - m_minX;
    int height = m_maxY - m_minY;

    double nw = dsx * 1.0;
    double nh = dsy * 1.0;

    double factorx,factory;
    if (width != 0)
    {
        factorx = nw/(double)width;
    }
    else
    {
        factorx = 1;
    }

    if (height != 0)
    {
        factory = nh/(double)height;
    }
    else
    {
        factory = 1;
    }

    pDsHead->beginX *= factorx;
    pDsHead->beginY *= factory;

    // 数据缩放
    for (int j = 0; j < stepsize; j++)
    {
        double ax = absDataPtr->ax;
        double ay = absDataPtr->ay;

        ax *= factorx;
        ay *= factory;

        absDataPtr->ax = ax;
        absDataPtr->ay = ay;

        absDataPtr++;
    }

    m_editedflag = 1;

    return 1;
}

int EmbData::setMirror(int mirror)
{
    if (mirror == 0)    // 0, 无镜像; 1, 水平镜像; 2, 垂直镜像; 3, 水平和垂直镜像
    {
        return 0;
    }

    int mirrorx = 1; //x轴
    int mirrory = 1; //y轴
    int mirrorr = 0;
    int mirrorrdir = 0;

    if(mirror == 1 || mirror == 3)
    {
        mirrorx = -1;
    }
    if(mirror == 2 || mirror == 3)
    {
        mirrory = -1;
    }

    if(mirror == 1)
    {
        mirrorr = 1*PI*10000;
        mirrorrdir = -1;
    }
    else if (mirror == 2)
    {
        mirrorr = 2*PI*10000;
        mirrorrdir = -1;
    }
    else if (mirror == 3)
    {
        mirrorr = 1*PI*10000;
        mirrorrdir = 1;
    }

    // 文件头
    const QByteArray & ary = m_embAbsData;
    int size = ary.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary  data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("dat data size err");
        return -1;
    }

    DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());

    //在最大最小xy中 对起始点进行镜像处理

    int bx = pDsHead->beginX;
    int by = pDsHead->beginY;

    if(mirrorx == -1)
        pDsHead->beginX = pDsHead->maxX - (bx - pDsHead->minX);
    if(mirrory == -1)
        pDsHead->beginY = pDsHead->maxY - (by - pDsHead->minY);

    //beginR的旋转
    double br = pDsHead->beginR;
    if (mirrorrdir > 0)
    {
        br = br + mirrorr;
    }
    else if (mirrorrdir < 0)
    {
        br = mirrorr - br;
    }

    while (br > 2*PI * 10000)
    {
        br -= 2*PI * 10000;
    }
    while (br < -2*PI * 10000)
    {
        br += 2*PI * 10000;
    }
    pDsHead->beginR = br;

    DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;

    // 数据镜像
    for (int j = 0; j < stepsize; j++)
    {
        double ax = absDataPtr->ax;
        double ay = absDataPtr->ay;
        double ar = absDataPtr->ar;

        int rx = ax * mirrorx; //相对坐标 乘负数则数据镜像
        int ry = ay * mirrory;

        if (mirrorrdir > 0)
        {
            ar = ar + mirrorr;
        }
        else if (mirrorrdir < 0)
        {
            ar = mirrorr - ar;
        }

        while (ar > 2*PI * 10000)
        {
            ar -= 2*PI * 10000;
        }
        while (ar < -2*PI * 10000)
        {
            ar += 2*PI * 10000;
        }

        absDataPtr->ax = rx;
        absDataPtr->ay = ry;
        absDataPtr->ar = ar;

        absDataPtr++;
    }

    m_editedflag = 1;
    return 1;
}

//flag :true代表顺时针方向
int EmbData::setRotate90(bool flag)
{

    // 文件头
    const QByteArray & ary = m_embAbsData;
    int size = ary.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary  data less then head size");
        return -1;
    }
    int datasize = size - sizeof(DataDs16FileHead);
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("dat data size err");
        return -1;
    }
    DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());

    int maxX = pDsHead->maxX;
    int maxY = pDsHead->maxY;

    int bx = pDsHead->beginX;
    int by = pDsHead->beginY;

    if(flag){   //正向旋转90
        pDsHead->beginX =  maxY - by;
        pDsHead->beginY = bx;
    }
    else{
        pDsHead->beginX = by;
        pDsHead->beginY = maxX - bx;
    }

    DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;

    for (int j = 0; j < stepsize; j++)
    {
        double ax = absDataPtr->ax;
        double ay = absDataPtr->ay;

        int rx, ry;
        if(flag){   //正向旋转90
            rx = -ay;
            ry = ax;
        }else{
            rx = ay;
            ry = -ax;
        }

        absDataPtr->ax = rx;
        absDataPtr->ay = ry;

        absDataPtr++;
    }

    m_editedflag = 1;
    return 1;

}

///
/// \brief //获得下一个图元的第一缝纫针步
/// \param curIndex
/// \return
///
int EmbData::getNextElementIndex(int curIndex)
{
    // ds16数据
    int size = m_embDs16Data.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("16 data less then head size");
        return -1;
    }
    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("dat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(Ds16Item);
    if (stepsize <= 0)
    {
        qDebug("ds16 data size err");
        return -1;
    }

    Ds16Item * ds16DataPtr = (Ds16Item *)(m_embDs16Data.data() + sizeof(DataDs16FileHead));
    ds16DataPtr = ds16DataPtr + curIndex;

    u8 curByte =ds16DataPtr->ctrl; //当前状态
    ds16DataPtr ++;
    curIndex ++;

    int i = curIndex;
    for (; i < stepsize; i++)
    {

        if(curByte != DATA_SEWING)
        {
            if(ds16DataPtr->ctrl == DATA_SEWING)
                break;
        }else{
            if(ds16DataPtr->ctrl != DATA_SEWING)
                curByte = ds16DataPtr->ctrl;
        }
        ds16DataPtr++;
    }
    return i;
}

///
/// \brief //上一个图元(当前为跨步时)或当前图元(当前为缝纫时)的第一缝纫针步
/// \param curIndex
/// \return
///
int EmbData::getPreOrThisElementIndex(int curIndex)
{
    // ds16数据
    int size = m_embDs16Data.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("16 data less then head size");
        return -1;
    }
    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("dat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(Ds16Item);
    if (stepsize <= 0)
    {
        qDebug("ds16 data size err");
        return -1;
    }

    Ds16Item * ds16DataPtr = (Ds16Item *)(m_embDs16Data.data() + sizeof(DataDs16FileHead));
    ds16DataPtr = ds16DataPtr + curIndex;

    u8 curByte =ds16DataPtr->ctrl; //当前状态
    ds16DataPtr--;
    curIndex --;

    int i = curIndex;

    for (; i > 0; i--)
    {
        //如果当前是缝纫数据，找到其他的就返回下一针
        if(curByte == DATA_SEWING)
        {
            if(ds16DataPtr->ctrl != DATA_SEWING)
                break;
        }else{
            //找到其他的就返回下一针
            if(ds16DataPtr->ctrl == DATA_SEWING)
                curByte = DATA_SEWING;
        }
        ds16DataPtr--;
    }
    return ++i;
}

//-------------------------------------------------
// 分割切刀数据(裁床专用代码)
//
#define     CUT_MINST_STP       (5.0)           // 拟合小针步,小于此值的针步将被合并,单位0.01mm
#define     CUT_LINE_MIN_STP    (20.0)          // 直线最小步长,单位0.01mm
#define     CUT_LINE_MAX_STP    (800.0)         // 直线最大步长,单位0.01mm

#define     CUT_ROUD_ANG        (ANGLECORR)     // 圆弧转角判断度数,单位:10000弧度
#define     CUT_ROUD_STP        (10.0)          // 圆弧补偿步长,单位0.01mm
#define     CUT1_RADIUS         (50.0)          // 切刀1圆弧补偿半径,精度0.01mm
#define     CUT2_RADIUS         (50.0)          // 切刀2圆弧补偿半径,精度0.01mm

// 分割直线 (匀变步长 分割针步)
// 返回值:       增加的针数
// posX1,posY1: 起点坐标
// posX2,posY2: 起点坐标
// stepMin:     最小分割针步大小
// stepMax:     最大分割针步大小

// 分割直线
int EmbData::splittingLine(double posX1, double posY1,
                           double posX2, double posY2,
                           int stepMin, int stepMax,
                           QByteArray &cutData, DsAbsItem item)
{
    int num = 0;    // 增加的针步数
    if ((stepMin == 0) || (stepMax == 0))
    {
        return -1;
    }

    DsAbsItem absItem;

    // 线段长
    double len = sqrt((posX1-posX2)*(posX1-posX2)+(posY1-posY2)*(posY1-posY2));

    if (len <= stepMin)
    {
        memcpy(&absItem,&item,sizeof(DsAbsItem));
        num++;
        cutData.append((char*)(&absItem), sizeof(DsAbsItem));    // 中间数据
    }
    else
    {// 分割份数
        int n = (int)(len/stepMin + 0.5);

        int i,j ;
        double add;

        j = stepMin;
        add = 0;
        for (i=0; i<(n/2);i++)
        {// 扫描匀速点和降速点
            add += j;
            j += stepMin;

            if (((add*2)>= len) ||
                    (j >= stepMax) ||
                    0)
            {
                break;
            }
        }

        int n1 = i;  // 匀速点
        int n2 = n-n1-2;  // 减速点

        j = 1;
        add = 1;

        for (i=1; i<=n;i++)
        {
            if (i >= add)
            {
                add += j;
                if (add > n)
                {
                    add = n;
                }

                if ((i >= n2) && (j > 2))
                {
                    j--;
                }
                else if (i < n1)
                {
                    j++;
                }


                memcpy(&absItem,&item,sizeof(DsAbsItem));
                absItem.ax = posX1+(posX2-posX1)*i/n;
                absItem.ay = posY1+(posY2-posY1)*i/n;
                num++;
                cutData.append((char*)(&absItem), sizeof(DsAbsItem));    // 中间数据
            }
        }
    }

    return num;
}


// 分割圆弧
// 返回值:       增加的针数
// posX1,posY1: 起点坐标
// posX2,posY2: 起点坐标
// xc,yc,r:		圆心,半径
// dr1,dr2:     起点,终点角度
// step:        分割针步大小

// 分割圆弧
int EmbData::splittingArc(double posX1, double posY1,
                          double posX2, double posY2,
                          double xc, double yc, double r,
                          double dr1,double dr2,int step,
                          QByteArray &cutData, DsAbsItem item)
{
    int num = 0;
    int dir = 1;

    // 弦长
    double len = sqrt((posX1-posX2)*(posX1-posX2)+(posY1-posY2)*(posY1-posY2));
    // 圆心角
    double k = (r*r+r*r-len*len)/(2*r*r);
    if (k < -1)
    {
        k = -1;
    }
    else if (k > 1)
    {
        k = 1;
    }

    double alph = acos(k);

    if (0)      // 执行此代码生成大圆弧
    {
        alph = PI*2 - alph;
    }

    if (1)
    {// 求旋转方向
        dr1 = dr1*-180/PI10000;
        dr2 = dr2*-180/PI10000;
        //qDebug()<<"bdr1="<<(dr1)<<",bdr2="<<(dr2);


        do
        {// 将dr1变换到整数
            if ((dr1 >= 0) && (dr1 < 360))    { break; }
            else if (dr1 < 0)                 { dr1 += 360; }
            else if (dr1 >= 360)              { dr1 -= 360; }
        }while(1);

        do
        {// 将dr2变换到整数
            if ((dr2 >= 0) && (dr2 < 360))    { break; }
            else if (dr2 < 0)                 { dr2 += 360; }
            else if (dr2 >= 360)              { dr2 -= 360; }
        }while(1);


        if (((dr1 <= 180) && (dr2 <= 180)) ||
                ((dr1 > 180) && (dr2 > 180)) ||
                0 )
        {
            if (dr1 < dr2)
            {
                dir = -1;   // 逆时针(正转)
            }
            else
            {
                dir = 1;    // 顺时针(反转)
            }
        }
        else if ((dr1 > 180) && (dr2 <= 180))
        {
            if ((dr1-180) > dr2)
            {
                dir = -1;   // 逆时针(正转)
            }
            else
            {
                dir = 1;    // 顺时针(反转)
            }
        }
        else if ((dr1 <= 180) && (dr2 > 180))
        {
            if ((dr1+180) > dr2)
            {
                dir = -1;   // 逆时针(正转)
            }
            else
            {
                dir = 1;    // 顺时针(反转)
            }
        }
        //   qDebug()<<"edr1="<<(int)(dr1+0.5)<<",edr2="<<(int)(dr2+0.5)<<",dir="<<dir;
    }


    // 弧长
    len = alph*r;

    // 分割份数
    int n = (int)(len/step + 0.5);

    // 增加的角度和方向
    double inc;
    inc = alph/n;
    inc *= dir;

    if (inc == 0)
    {
        return -1;
    }

    double lastx, lasty;
    double xrot, yrot;
    double ex, ey;

    lastx = posX1;
    lasty = posY1;

    int i = 0;
    DsAbsItem absItem;

    memcpy(&absItem,&item,sizeof(DsAbsItem));
    absItem.ax = posX1;
    absItem.ay = posY1;
    num++;
    cutData.append((char*)(&absItem), sizeof(DsAbsItem));    // 第一针

    do
    {// 点 (lastx, lasty) 在圆上旋转
        {// 旋转坐标值
            xrot=(lastx-xc)*cos(inc) - (lasty-yc)*sin(inc);
            yrot=(lastx-xc)*sin(inc) + (lasty-yc)*cos(inc);
        }

        lastx = xrot + xc;
        lasty = yrot + yc;

        ex = lastx;
        ey = lasty;

        memcpy(&absItem,&item,sizeof(DsAbsItem));
        absItem.ax = ex;
        absItem.ay = ey;

        if (((fabs(lastx-posX2) > 1) || (fabs(lasty-posY2) > 1)) &&
                (i < (n-1)) &&
                1)
        {// 圆弧中间 增加降速抬刀标志
            absItem.attr |= 0x10;
        }
        num++;
        cutData.append((char*)(&absItem), sizeof(DsAbsItem));

        i++;

        if ((fabs(lastx-posX2) <= 1) && (fabs(lasty-posY2) <= 1))
        {
            ex = posX2;
            ey = posY2;

            memcpy(&absItem,&item,sizeof(DsAbsItem));
            absItem.ax = ex;
            absItem.ay = ey;

            num++;
            cutData.append((char*)(&absItem), sizeof(DsAbsItem));
            break;
        }
    } while(i < n);

    return num;
}

// 偏心刀平板切割机补偿算法
// 增加对比数据
int EmbData::setCutcontrastData( )
{
    int cutLineMaxStp = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutLineMaxStp").toInt();
    if (cutLineMaxStp == 0)
    {
        cutLineMaxStp = 100;
    }

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步

    DsAbsItem absItem;

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();

    double begX;	// 起始点
    double begY;

    // 数据区
    {
        absDataPtr = pData;  //中间数据针步

        for (int j = 0; j < stepsize; j++)
        {
            if ((absDataPtr->ctrl == DATA_NULL) || (absDataPtr->ctrl == DATA_END))
            {
                //   memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                //   newstepnum++;
                //   cutAbsData.append((char*)(absDataPtr), sizeof(DsAbsItem));
            }
            else
            {
                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                newstepnum++;
                cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
            }

            absDataPtr++;
        }
    }

    // 参考数据
    if (1)
    {
        absDataPtr = pData;  //中间数据针步

        for (int j = 0; j < stepsize; j++)
        {
            if ((absDataPtr->ctrl == DATA_NULL) || (absDataPtr->ctrl == DATA_END))
            {
                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                newstepnum++;
                cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
            }
            else
            {
                if (j == 0)
                {
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    absItem.ctrl = DATA_OFFSET;
                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                }
                else
                {// 分割针步

                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    absItem.ctrl = DATA_OFFSET;
                    newstepnum += splittingLine(begX, begY, absDataPtr->ax, absDataPtr->ay,
                                                cutLineMaxStp, cutLineMaxStp,
                                                cutAbsData, absItem);   // 分割直线
                }

                begX = absDataPtr->ax;
                begY = absDataPtr->ay;
            }
            absDataPtr++;
        }
    }


    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    return 0;
}

// 增加拐点数据
int EmbData::setCutCornerStep()
{
    int cutRoudAng  = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutRoudAng").toInt();
    cutRoudAng = cutRoudAng * 10000 * PI / 18000;       // 角度->10000弧度

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步

    DsAbsItem absItem;

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();

    double nf1r = 0;	// 切刀1角度
    double nf2r = 0;	// 切刀2角度

    // 将数据中最后一段的角度赋值给起始角度
    for (int j = 0; j < stepsize; j++)
    {
        if (absDataPtr->ctrl == DATA_EKNIFE1)
        {// 切刀1 角度
            nf1r= absDataPtr->ar;
        }
        else if (absDataPtr->ctrl == DATA_EKNIFE2)
        {// 切刀2 角度
            nf2r= absDataPtr->ar;
        }
        absDataPtr++;
    }

    absDataPtr = pData;  //中间数据针步
    for (int j = 0; j < stepsize; j++)
    {
        if ((absDataPtr->ctrl == DATA_NULL) || (absDataPtr->ctrl == DATA_END))
        {
            memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
            newstepnum++;
            cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
        }
        else
        {
            if (j == 0)
            {
                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                newstepnum++;
                cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
            }
            else if (absDataPtr->ctrl == DATA_EKNIFE1)
            {// 切刀1 补偿
                double dr = abs(absDataPtr->ar - nf1r);
                if (dr >= cutRoudAng)
                {// 判断夹角
                    absDataPtr--;       // 前一针的位置(圆心)
                    double x = absDataPtr->ax;
                    double y = absDataPtr->ay;

                    absDataPtr++;       // 当前针
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    absItem.ax = x;
                    absItem.ay = y;
                    absItem.attr |= 0x20;      // 临时增加拐点标志

                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));

                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                }
                else
                {
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                }

                nf1r = absDataPtr->ar;
            }
            else if (absDataPtr->ctrl == DATA_EKNIFE2)
            {// 切刀2 补偿
                double dr = abs(absDataPtr->ar - nf2r);
                //                qDebug()<<"dr:"<<dr;
                if (dr >= cutRoudAng)
                {// 判断夹角
                    absDataPtr--;       // 前一针的位置(圆心)
                    double x = absDataPtr->ax;
                    double y = absDataPtr->ay;

                    absDataPtr++;       // 当前针
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    absItem.ax = x;
                    absItem.ay = y;
                    absItem.attr |= 0x20;      // 临时增加拐点标志

                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));

                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                }
                else
                {
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                }

                nf2r = absDataPtr->ar;
            }
            else
            {//
                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                newstepnum++;
                cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));    // 保存当前针信息
            }
        }
        absDataPtr++;
    }


    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    return 0;
}

// 偏心刀刀尖补偿(裁床专用代码)
int EmbData::setCutEccentricCompensation()
{
    int cut1Radius  =  g_pSettings->readFromIniFile("FlatPanelAlgorithm/cut1Radius").toInt();
    int cut2Radius = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cut2Radius").toInt();
    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步

    DsAbsItem absItem;

    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();
    // 数据区
    for (int j = 0; j < stepsize; j++)
    {
        if ((absDataPtr->ctrl == DATA_NULL) || (absDataPtr->ctrl == DATA_END))
        {
            cutAbsData.append((char*)(absDataPtr), sizeof(DsAbsItem));
        }
        else
        {
            if (j == 0)
            {
                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
            }
            else if (absDataPtr->ctrl == DATA_EKNIFE1)
            {// 切刀1 补偿
                double crt = cut1Radius*1.0;               // 分割量
                double r = (absDataPtr->ar) / 10000.0;      // 角度(弧度制)
                double cosr = (double)qCos(r);
                double sinr = (double)qSin(r);
                double tx = cosr * (crt*1.0);
                double ty = sinr * (crt*1.0);

                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                absItem.ax += tx;
                absItem.ay += ty;
                cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
            }
            else if (absDataPtr->ctrl == DATA_EKNIFE2)
            {// 切刀2 补偿
                double crt = cut2Radius*1.0;               // 分割量
                double r = (absDataPtr->ar) / 10000.0;      // 角度(弧度制)
                double cosr = (double)qCos(r);
                double sinr = (double)qSin(r);
                double tx = cosr * (crt*1.0);
                double ty = sinr * (crt*1.0);

                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                absItem.ax += tx;
                absItem.ay += ty;
                cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
            }
            else
            {//
                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
            }
        }
        absDataPtr++;
    }

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    return 0;
}

// 增加两端补偿
// 输入
int EmbData:: setCutAddCutterComption()
{
    //int cutRnf1Comp =  g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutRnf1Comp").toInt();
    int cutRnf2Comp =  g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutRnf2Comp").toInt();

    if (cutRnf2Comp == 0)
    {
        return 0;
    }

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步

    if (0)
    {
        pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
        absDataPtr = pData;  //中间数据针步

        for (int j = 0; j < stepsize;j++)
        {
            qDebug()<<"3 idx:"<<j
                   <<"  ctrl:"<<absDataPtr->ctrl
                  <<"  attr:"<<absDataPtr->attr
                 <<"  x:"<<absDataPtr->ax
                <<"  y:"<<absDataPtr->ay
                  ;
            absDataPtr++;
        }
    }

    int begFlg = 0;

    DsAbsItem absItem;

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();

    {
        absDataPtr = pData;  //中间数据针步
        for (int j = 0; j < stepsize;j++)
        {
            if ((j == 0) ||
                    (absDataPtr->ctrl == DATA_OFFSET) ||        // 偏移
                    (absDataPtr->ctrl == DATA_NULL) ||
                    (absDataPtr->ctrl == DATA_END) ||
                    (absDataPtr->ctrl == DATA_DRAWING) ||        // 画笔
                    0 )
            {// 找到起点
                begFlg = 0;
                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                newstepnum++;
                cutAbsData.append((char*)(absDataPtr), sizeof(DsAbsItem));
            }
            else
            {
                if (begFlg == 0)
                {// 增加起始补偿数据
                    begFlg = 1; // 起始点标志
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    newstepnum++;
                    cutAbsData.append((char*)(absDataPtr), sizeof(DsAbsItem));
                }
                else
                {
                    absDataPtr++;
                    if ((absDataPtr->ctrl == DATA_NULL) ||
                            (absDataPtr->ctrl == DATA_END) ||
                            (absDataPtr->ctrl == DATA_OFFSET)    ||        // 偏移
                            (absDataPtr->ctrl == DATA_DRAWING)   ||        // 画笔
                            0 )
                    {// 增加收尾补偿数据
                        absDataPtr--;

                        double crt = cutRnf2Comp*1.0;              // 补偿量
                        double r = (absDataPtr->ar) / 10000.0;      // 角度(弧度制)
                        double cosr = (double)qCos(r);
                        double sinr = (double)qSin(r);
                        double tx = cosr * (crt*1.0);
                        double ty = sinr * (crt*1.0);

                        memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));

                        absItem.ax += tx;
                        absItem.ay += ty;

                        newstepnum++;
                        cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));

                    }
                    else
                    {
                        absDataPtr--;
                        // 复制当前针步
                        memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                        newstepnum++;
                        cutAbsData.append((char*)(absDataPtr), sizeof(DsAbsItem));

                    }
                }
            }
            absDataPtr++;
        }
    }

    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    if (0)
    {
        pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
        absDataPtr = pData;  //中间数据针步

        for (int j = 0; j < newstepnum;j++)
        {
            qDebug()<<"4 idx:"<<j
                   <<"  ctrl:"<<absDataPtr->ctrl
                  <<"  attr:"<<absDataPtr->attr
                 <<"  x:"<<absDataPtr->ax
                <<"  y:"<<absDataPtr->ay
                  ;
            absDataPtr++;
        }
    }
    return 0;
}

// 增加转刀数据(裁床专用代码)
int EmbData::setCutRotaryCutterData()
{
    int cutRoudStp  = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutRoudStp").toInt();
    int cut1Radius = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cut1Radius").toInt();
    int cut2Radius  = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cut2Radius").toInt();

    if (cutRoudStp == 0)
    {
        cutRoudStp = 10;
    }
    if (cut1Radius == 0)
    {
        return 0;
    }
    if (cut2Radius == 0)
    {
        return 0;
    }

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步

    DsAbsItem absItem;

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();

    double nf1r = 0;	// 切刀1角度
    double nf2r = 0;	// 切刀2角度

    // 将数据中最后一段的角度赋值给起始角度
    for (int j = 0; j < stepsize; j++)
    {
        if (absDataPtr->ctrl == DATA_EKNIFE1)
        {// 切刀1 角度
            nf1r= absDataPtr->ar;
        }
        else if (absDataPtr->ctrl == DATA_EKNIFE2)
        {// 切刀2 角度
            nf2r= absDataPtr->ar;
        }
        absDataPtr++;
    }

    if (0)
    {
        pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
        absDataPtr = pData;  //中间数据针步

        for (int j = 0; j < 100;j++)
        {
            qDebug()<<"5 idx:"<<j
                   <<"  ctrl:"<<absDataPtr->ctrl
                  <<"  attr:"<<absDataPtr->attr
                 <<"  x:"<<absDataPtr->ax
                <<"  y:"<<absDataPtr->ay
                  ;
            absDataPtr++;
        }
    }


    double crt;             // 分割量
    double r;               // 角度(弧度制)
    double tx;
    double ty;

    double posX1,posY1;     // 起点
    double posX2,posY2;     // 终点
    double xc,yc,rc;        // 圆心半径
    double dr1,dr2;         // 起始,终止角度
    int    step;            // 针步
    int    num;             // 增加针数
    u8     ctrlold;         //

    absDataPtr = pData;  //中间数据针步
    // 数据区
    for (int j = 0; j < stepsize; j++)
    {
        if ((absDataPtr->ctrl == DATA_NULL) || (absDataPtr->ctrl == DATA_END))
        {
            memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
            newstepnum++;
            cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
        }
        else
        {
            if (j == 0)
            {
                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                newstepnum++;
                cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
            }
            else if (absDataPtr->ctrl == DATA_EKNIFE1)
            {// 切刀1 补偿
                if ((absDataPtr->attr & 0x20) == 0x20)
                {// 拐点位置针步
                    crt = cut1Radius*1.0;          //
                    posX2 = absDataPtr->ax;         // 终点
                    posY2 = absDataPtr->ay;

                    r = (absDataPtr->ar) / 10000.0;      // 角度(弧度制)
                    tx = (double)qCos(r) * (crt*1.0);
                    ty = (double)qSin(r) * (crt*1.0);

                    xc    = absDataPtr->ax - tx;    // 圆心
                    yc    = absDataPtr->ay - ty;

                    r = (nf1r) / 10000.0;           // 角度(弧度制)
                    tx = (double)qCos(r) * (crt*1.0);
                    ty = (double)qSin(r) * (crt*1.0);

                    posX1    = xc + tx;             // 起点
                    posY1    = yc + ty;

                    rc    = cut1Radius*1.0;        // 半径
                    dr1   = nf1r;                   // 起始角度
                    dr2   = absDataPtr->ar;         // 终止角度
                    step  = cutRoudStp*1.0;       // 步长

                    if (ctrlold != DATA_EKNIFE1)
                    {// 在起点增加偏移数据
                        memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                        absItem.ctrl = DATA_OFFSET;
                        absItem.attr = 0;
                        absItem.ax = posX1;
                        absItem.ay = posY1;
                        newstepnum++;
                        cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                    }
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    num = splittingArc(posX1, posY1, posX2, posY2,
                                       xc, yc, rc, dr1, dr2, step,
                                       cutAbsData, absItem);

                    newstepnum += num;
                }
                else
                {
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                }

                nf1r = absDataPtr->ar;
            }
            else if (absDataPtr->ctrl == DATA_EKNIFE2)
            {// 切刀2 补偿
                if ((absDataPtr->attr & 0x20) == 0x20)
                {// 拐点位置针步
                    crt = cut2Radius*1.0;          //
                    posX2 = absDataPtr->ax;         // 终点
                    posY2 = absDataPtr->ay;

                    r = (absDataPtr->ar) / 10000.0;      // 角度(弧度制)
                    tx = (double)qCos(r) * (crt*1.0);
                    ty = (double)qSin(r) * (crt*1.0);

                    xc    = absDataPtr->ax - tx;    // 圆心
                    yc    = absDataPtr->ay - ty;

                    r = (nf2r) / 10000.0;           // 角度(弧度制)
                    tx = (double)qCos(r) * (crt*1.0);
                    ty = (double)qSin(r) * (crt*1.0);

                    posX1    = xc + tx;             // 起点
                    posY1    = yc + ty;

                    rc    = cut2Radius*1.0;        // 半径
                    dr1   = nf2r;                   // 起始角度
                    dr2   = absDataPtr->ar;         // 终止角度
                    step  = cutRoudStp*1.0;       // 步长

                    if (ctrlold != DATA_EKNIFE2)
                    {// 在起点增加偏移数据
                        memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                        absItem.ctrl = DATA_OFFSET;
                        absItem.attr = 0;
                        absItem.ax = posX1;
                        absItem.ay = posY1;
                        newstepnum++;
                        cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                    }

                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    num = splittingArc(posX1, posY1, posX2, posY2,
                                       xc, yc, rc, dr1, dr2, step,
                                       cutAbsData, absItem);

                    newstepnum += num;
                }
                else
                {
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                }

                nf2r = absDataPtr->ar;
            }
            else
            {//
                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                newstepnum++;
                cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
            }
        }

        ctrlold = absDataPtr->ctrl;
        absDataPtr++;
    }

    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数
    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    if (0)
    {
        pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
        absDataPtr = pData;  //中间数据针步

        for (int j = 0; j < 100;j++)
        {
            qDebug()<<"6 idx:"<<j
                   <<"  ctrl:"<<absDataPtr->ctrl
                  <<"  attr:"<<absDataPtr->attr
                 <<"  x:"<<absDataPtr->ax
                <<"  y:"<<absDataPtr->ay
                  ;
            absDataPtr++;
        }
    }
    return 0;
}

//  去掉拐点数据
int EmbData::setCutDecCornerStep()
{
    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步

    if (0)
    {
        pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
        absDataPtr = pData;  //中间数据针步

        for (int j = 0; j < stepsize;j++)
        {
            qDebug()<<"7 idx:"<<j
                   <<"  ctrl:"<<absDataPtr->ctrl
                  <<"  attr:"<<absDataPtr->attr
                 <<"  x:"<<absDataPtr->ax
                <<"  y:"<<absDataPtr->ay
                  ;
            absDataPtr++;
        }

        absDataPtr = pData;  //中间数据针步
    }

    DsAbsItem absItem;

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();

    for (int j = 0; j < stepsize; j++)
    {
        if ((absDataPtr->ctrl == DATA_NULL) || (absDataPtr->ctrl == DATA_END))
        {
            memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
            newstepnum++;
            cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
        }
        else
        {
            if (1)// ((absDataPtr->ax != 0) || (absDataPtr->ay != 0)) // 不是第一针
            {
                if (absDataPtr->ctrl != DATA_EKNIFE1)
                {
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));

                    absDataPtr++;
                    if ((absDataPtr->ctrl == DATA_EKNIFE1) &&
                            ((absDataPtr->attr & 0x20) == 0x20) &&
                            1 )
                    {// 当前针是偏移,下一针是转刀补偿数据,将偏移数据的位置指向转刀补偿数据的起点
                        absItem.ax = absDataPtr->ax;
                        absItem.ay = absDataPtr->ay;
                    }
                    absDataPtr--;

                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                }
                else if (absDataPtr->ctrl != DATA_EKNIFE2)
                {
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));

                    absDataPtr++;
                    if ((absDataPtr->ctrl == DATA_EKNIFE2) &&
                            ((absDataPtr->attr & 0x20) == 0x20) &&
                            1 )
                    {// 当前针是偏移,下一针是转刀补偿数据,将偏移数据的位置指向转刀补偿数据的起点
                        absItem.ax = absDataPtr->ax;
                        absItem.ay = absDataPtr->ay;
                    }
                    absDataPtr--;

                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                }
                else
                {
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                }
            }
        }

        absDataPtr++;
    }


    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    if (0)
    {
        pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
        absDataPtr = pData;  //中间数据针步

        for (int j = 0; j < newstepnum;j++)
        {
            qDebug()<<"8 idx:"<<j
                   <<"  ctrl:"<<absDataPtr->ctrl
                  <<"  attr:"<<absDataPtr->attr
                 <<"  x:"<<absDataPtr->ax
                <<"  y:"<<absDataPtr->ay
                  ;
            absDataPtr++;
        }
    }
    return 0;
}

// 分割切刀数据
int EmbData::setCutFitSplitStep()
{
    int cutLineMinStp = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutLineMinStp").toInt();
    int cutLineMaxStp  = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutLineMaxStp").toInt();
    if (cutLineMinStp == 0)
    {
        cutLineMinStp = 10;
    }

    if (cutLineMaxStp == 0)
    {
        cutLineMaxStp = 10;
    }

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步

    DsAbsItem absItem;

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();

    double begX;	// 起始点
    double begY;

    // 数据区
    {
        for (int j = 0; j < stepsize; j++)
        {
            if ((absDataPtr->ctrl == DATA_NULL) || (absDataPtr->ctrl == DATA_END))
            {
                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                newstepnum++;
                cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
            }
            else
            {
                if (j == 0)
                {
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                }
                else
                {// 分割针步
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    newstepnum += splittingLine(begX, begY, absDataPtr->ax, absDataPtr->ay,
                                                cutLineMaxStp, cutLineMaxStp,
                                                cutAbsData, absItem);   // 分割直线
                }

                begX = absDataPtr->ax;
                begY = absDataPtr->ay;
            }
            absDataPtr++;
        }
    }


    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    return 0;
}

// 拟合切刀数据(过滤小针步)
int EmbData::setCutFitStepData()
{
    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步

    DsAbsItem absItem;
    DsAbsItem absItemOld;

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();

    // 数据区
    {
        for (int j = 0; j < stepsize; j++)
        {
            if ((absDataPtr->ctrl == DATA_NULL) || (absDataPtr->ctrl == DATA_END))
            {
                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                newstepnum++;
                cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
            }
            else
            {
                if (j == 0)
                {
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    absItem.attr &= ~0x20;      // 删除拐点标志
                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                    memcpy(&absItemOld,absDataPtr,sizeof(DsAbsItem));
                }
                else
                {// 分割针步
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));

                    // 线段长
                    double len = sqrt((absItem.ax-absItemOld.ax)*(absItem.ax-absItemOld.ax)+
                                      (absItem.ay-absItemOld.ay)*(absItem.ay-absItemOld.ay));

                    if ((len <= CUT_MINST_STP) &&
                            (absItem.ctrl   == absItemOld.ctrl   ) &&
                            //(absItem.action == absItemOld.action ) &&
                            //(absItem.attr   == absItemOld.attr   ) &&
                            1)
                    {// 滤掉小针步
                    }
                    else
                    {
                        absItem.attr &= ~0x20;      // 删除拐点标志
                        newstepnum++;

                        double tar = atan2(absItem.ay,absItem.ax);
                        absItem.ar = (tar * 10000+0.5*(tar>0?1:-1));

                        cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                        memcpy(&absItemOld,absDataPtr,sizeof(DsAbsItem));
                    }
                }
            }
            absDataPtr++;
        }
    }

    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    return 0;
}

// 飞行切割平板切割机补偿算法    coco
//#define     CUT_CRUTCH_ANG        (ANGLECORR)           // 拐点转角判断度数,单位:10000弧度
//#define     CUT_LINE_STP          (3000)               // 分割数据步长,单位0.01mm
//#define     CUT_X_LENGH           (500000)              // X向可切割长度,单位0.01mm
//#define     CUT_X_WINDOW          (CUT_X_LENGH*3/10)    // X向过窗长度:3/10
//#define     CUT_X_EDGE            (CUT_X_LENGH/10)      // X向过窗边缘 1/10
//#define     CUT_RNF_COMP          (10.00)               // 圆刀退刀补偿 ,单位0.01mm

#define     CUT_OFFSET_SPD        (80000)              // 偏移速度 ,单位0.01mm/s
#define     CUT_DRAWING_SPD       (60000)              // 画笔速度 ,单位0.01mm/s
#define     CUT_CUTTING_SPD       (40000)              // 切割速度 ,单位0.01mm/s
#define     CUT_LEFT_TIME         (1)                   // 升降机头时间 ,单位s
#define     CUT_SPD_ADJ           (100)                 // 行进速度校准 ,范围50%~200% 单位%
#define     CUT_SPD_MAX           (30000)               // 最大行进速度 ,单位0.01mm/s   (1~65500)

// 打印当前数据
int EmbData:: outputCurStepData()
{
    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步

    DsAbsItem absItem;

    for (int j = 0; j < stepsize; j++)
    {
        memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
        qDebug()<<"idx:"<<j <<"  ctrl:"<<absDataPtr->ctrl
               <<"  act:"<<absDataPtr->action
              <<"  attr:"<<absDataPtr->attr
             <<"  r:"<<absDataPtr->ar<<"  x:"<<absDataPtr->ax/100  <<"  y:"<<absDataPtr->ay/100;
        absDataPtr++;
    }
    return 0;
}

// 增加拐点数据
int EmbData:: setCut2CornerStep()
{
    double cutCrutchAng = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutCrutchAng").toDouble();
    if (cutCrutchAng <= 0)
    {
        cutCrutchAng = 60.0;
    }

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步

    DsAbsItem absItem;//当前点
    DsAbsItem lastItem;//上一点

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();

    for (int j = 0; j < stepsize; j++)
    {
        memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));

        if ((j == 0) ||
                (absItem.ctrl == DATA_NULL) ||
                (absItem.ctrl == DATA_END) ||
                0 )
        {
            newstepnum++;
            cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));

            memcpy(&lastItem,&absItem,sizeof(DsAbsItem));//赋值上一点
        }
        else if (absItem.ctrl == DATA_OFFSET)
        {// 偏移数据
            newstepnum++;
            cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));

            memcpy(&lastItem,&absItem,sizeof(DsAbsItem));
        }
        else
        {
#if(1)
            double dr = qAbs(absItem.ar - lastItem.ar);
            //比较两线段之间夹角是否大于设定角度
            if ((dr >= (PI*10000*cutCrutchAng/180)) ||
                    (absItem.ctrl != lastItem.ctrl) ||
                    0 )
            {// 当两种控制字交替时,生成一个新数据(线迹起点)
                if ((absItem.ctrl != DATA_OFFSET) &&
                        (lastItem.ctrl != DATA_OFFSET) &&
                        1 )
                {// 如果前后两个控制字都不是偏移数据,插入一个拐点数据
                    absItem.ctrl = DATA_ANGLE_OLD;
                    absItem.ax = lastItem.ax;
                    absItem.ay = lastItem.ay;
                    //absItem.ar = lastItem.ar;

                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                }

                {// 新数据段起点
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    //absItem.ar = calculateAngles(absItem.ax, absItem.ay,(absDataPtr-1)->ax, (absDataPtr-1)->ay);//新增-角度计算
                    //absItem.ar = lastItem.ar;
                    absItem.ax = lastItem.ax;
                    absItem.ay = lastItem.ay;// +1 防止出现(x/y为0 空有角度的情况)

                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                }

                {// 新数据段
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));

                    memcpy(&lastItem,&absItem,sizeof(DsAbsItem));
                }
            }
            else
#endif
            {
                newstepnum++;
                cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));

                memcpy(&lastItem,&absItem,sizeof(DsAbsItem));
            }
        }

        absDataPtr++;
    }


    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    return 0;
}

// 修改数据方向
int EmbData:: setCut2ModifyDataDir()
{
    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步
    DsAbsItem * absDataPtrBuf = pData;  //中间数据针步

    DsAbsItem absItem;

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();

    double begX = 0.0 ,endX = 0.0;           // 起始点/终止点X坐标
    int  begIdx,endIdx = 0;         // 单个图元起始/终止点

    // 数据区
    {
        absDataPtr = pData;  //中间数据针步

        for (int j = 0; j < stepsize;)
        {
            qDebug()<<"idx:"<<j <<"  ctrl:"<<absDataPtr->ctrl <<"  r:"<<absDataPtr->ar <<"  x:"<<absDataPtr->ax  <<"  y:"<<absDataPtr->ay   ;

            if ((absDataPtr->ctrl == DATA_NULL) ||
                    (absDataPtr->ctrl == DATA_END) ||
                    0 )
            {
                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                newstepnum++;
                cutAbsData.append((char*)(absDataPtr), sizeof(DsAbsItem));

                j++;
                absDataPtr++;
            }
            else if (absDataPtr->ctrl == DATA_ANGLE_OLD)
            {// 找到起点拐点
                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                newstepnum++;
                cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                j++;
                absDataPtr++;

                {//判断下一个数据
                    begIdx = j;
                    begX = absDataPtr->ax;
                    absDataPtrBuf = absDataPtr;
                    for (int i = j; i < stepsize;i++)
                    {
                        if ((absDataPtrBuf->ctrl == DATA_ANGLE_OLD) ||
                                (absDataPtrBuf->ctrl == DATA_NULL) ||
                                (absDataPtrBuf->ctrl == DATA_END) ||
                                0 )
                        {
                            i--;
                            endIdx = i;
                            absDataPtrBuf--;
                            endX = absDataPtrBuf->ax;
                            break;
                        }
                        absDataPtrBuf++;
                    }

                    if ((begIdx != endIdx) &&
                            (endX < begX) &&
                            1 )
                    {// 反转数据
                        for (int i = endIdx; i >= begIdx;i--)
                        {
                            memcpy(&absItem,absDataPtrBuf,sizeof(DsAbsItem));
                            absItem.attr |= 0x01;       // 反向标志
                            absItem.ar += PI10000;       // 方向反向
                            newstepnum++;
                            cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                            qDebug()<<"idx:"<<j <<"  ctrl:"<<absDataPtr->ctrl <<"  r:"<<absDataPtr->ar <<"  x:"<<absDataPtr->ax  <<"  y:"<<absDataPtr->ay   ;

                            j++;
                            absDataPtr++;

                            absDataPtrBuf--;
                        }
                    }
                }
            }
            else
            {
                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                newstepnum++;
                cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));

                j++;
                absDataPtr++;
            }
        }
    }

    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    if (0)
    {
        pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
        absDataPtr = pData;  //中间数据针步

        for (int j = 0; j < stepsize;j++)
        {
            qDebug()<<"end idx:"<<j
                   <<"  ctrl:"<<absDataPtr->ctrl
                  <<"  r:"<<absDataPtr->ar
                 <<"  x:"<<absDataPtr->ax
                <<"  y:"<<absDataPtr->ay
                  ;
            absDataPtr++;
        }
    }
    return 0;
}

// 分割切刀数据
int EmbData:: setCut2FitSplitStep()
{
    int cutLineStp = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutLineStp").toInt();
    if(cutLineStp == 0)
    {
        cutLineStp = 800;
    }
    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步

    DsAbsItem absItem;

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();

    double begX;	// 起始点
    double begY;

    // 数据区
    {
        for (int j = 0; j < stepsize; j++)
        {
            if ((absDataPtr->ctrl == DATA_NULL) ||
                    (absDataPtr->ctrl == DATA_END) ||
                    //(absDataPtr->ctrl == DATA_OFFSET) ||
                    //(absDataPtr->ctrl == DATA_ANGLE_OLD) ||
                    0)
            {
                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                newstepnum++;
                cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
            }
            else
            {
                if (j == 0)
                {
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                }
                else
                {// 分割针步
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    newstepnum += splittingLine(begX, begY, absDataPtr->ax, absDataPtr->ay,
                                                cutLineStp, cutLineStp,
                                                cutAbsData, absItem);   // 分割直线
                }

                begX = absDataPtr->ax;
                begY = absDataPtr->ay;
            }
            absDataPtr++;
        }
    }


    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    if (0)
    {
        pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
        absDataPtr = pData;  //中间数据针步

        for (int j = 0; j < stepsize;j++)
        {
            qDebug()<<"end idx:"<<j
                   <<"  ctrl:"<<absDataPtr->ctrl
                  <<"  r:"<<absDataPtr->ar
                 <<"  x:"<<absDataPtr->ax
                <<"  y:"<<absDataPtr->ay
                  ;
            absDataPtr++;
        }
    }

    return 0;
}

// 判断区间
// 输入
//#define     CUT_X_LENGH           (500000)              // X向可切割长度
//#define     CUT_X_WINDOW          (CUT_X_LENGH*4/10)    // X向过窗长度:4/10
//#define     CUT_X_EDGE            (CUT_X_LENGH/10)      // X向过    窗边缘 1/10
int EmbData::setCut2JudgInterval()
{
    qDebug()<<__FUNCTION__;

    int cutXWindow = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutXLengh").toInt();
    if(cutXWindow == 0)
    {
        cutXWindow = 500000;
    }
    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步

    // 求花样X范围
    double maxX = S32_MIN;
    double minX = S32_MAX;

    absDataPtr = pData;  //中间数据针步
    for (int j = 0; j < stepsize; j++)
    {
        if (//(j == 0) ||
                (absDataPtr->ctrl == DATA_NULL) ||
                (absDataPtr->ctrl == DATA_END) ||
                (absDataPtr->ctrl == DATA_ANGLE_OLD) ||
                (absDataPtr->ctrl == DATA_OFFSET) ||
                0 )
        {
        }
        else
        {//
            if(absDataPtr->ax > maxX)
            {
                maxX = absDataPtr->ax;
            }
            if(absDataPtr->ax < minX)
            {
                minX = absDataPtr->ax;
            }
        }
        absDataPtr++;
    }

    // 分割窗口数量
    int winNum,curWin,begFlg;

    int maxWinX = 0;     // 当前窗口最大值
    int minWinX = 0;     // 当前窗口最小值

    curWin = 1;
    begFlg = 0;
    winNum = floor((maxX - minX) / (cutXWindow*4/10)) + 1;
    m_winnums = winNum;

    qDebug()<<"maxx:"<<maxX<<"  minx:"<<minX<<"  winNum:"<<winNum;

    DsAbsItem absItem;

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();

#if(1)
    {
        absDataPtr = pData;  //中间数据针步

        for (int j = 0; j < stepsize;j++)
        {
            if ((absDataPtr->ctrl == DATA_NULL) ||
                    (absDataPtr->ctrl == DATA_END) ||
                    0 )
            {
                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                newstepnum++;
                cutAbsData.append((char*)(absDataPtr), sizeof(DsAbsItem));
            }
            else if ((absDataPtr->ctrl == DATA_ANGLE_OLD) ||
                     (absDataPtr->ctrl == DATA_OFFSET)    ||
                     0 )
            {// 找到起点拐点
                begFlg = 0;
                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                newstepnum++;
                cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
            }
            else
            {
                double dtx = absDataPtr->ax - minX;

                if (begFlg == 0)
                {
                    begFlg = 1; // 起始点标志
                    curWin = floor(dtx / (cutXWindow*4/10));

                    maxWinX = (cutXWindow*4/10) * (curWin + 1)+ (cutXWindow/100);      // 当前窗口最大值
                    minWinX = (cutXWindow*4/10) * (curWin) - (cutXWindow/100);     // 当前窗口最小值
                    if (0)
                    {
                        qDebug()<<"curWin:"<<curWin
                               <<"  ax:"<<(absDataPtr->ax - minX)
                              <<"  Win:"<<(cutXWindow*4/10)
                             <<"  maxWinX:"<<maxWinX
                            <<"  minWinX:"<<minWinX
                              ;
                    }
                }

                if ((dtx < maxWinX) && (dtx >= minWinX))
                {// 当前窗口
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    absItem.action = curWin;
                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                }
                else if (dtx >= maxWinX)
                {// 下一个窗口
                    curWin++;
                    begFlg = 0;

                    memcpy(&absItem,(absDataPtr-1),sizeof(DsAbsItem)); //注释下方代码是修改后的，个人觉得对当前点做操作，不应该设计它前后的点
                    absItem.ctrl = DATA_ANGLE_OLD;
                    absItem.attr = 'm';
                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));    // 增加一个拐点

                    memcpy(&absItem,(absDataPtr-1),sizeof(DsAbsItem));
                    absItem.action = curWin;
                    absItem.attr = 'm';
                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));

                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    absItem.action = curWin;
                    absItem.attr = 'm';
                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                }
                else if (dtx < minWinX)
                {// 上一个窗口
                    curWin--;
                    begFlg = 0;

                    memcpy(&absItem,(absDataPtr-1),sizeof(DsAbsItem));
                    absItem.ctrl = DATA_ANGLE_OLD;
                    absItem.attr = 'm';
                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));    // 增加一个拐点

                    memcpy(&absItem,(absDataPtr-1),sizeof(DsAbsItem));
                    absItem.action = curWin;
                    absItem.attr = 'm';
                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));

                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    absItem.action = curWin;
                    absItem.attr = 'm';
                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                }
            }
            absDataPtr++;
        }
    }
#endif

    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    if (0)
    {
        pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
        absDataPtr = pData;  //中间数据针步

        for (int j = 0; j < newstepnum;j++)
        {
            qDebug()<<"end idx:"<<j
                   <<"  ctrl:"<<absDataPtr->ctrl
                  <<"  action:"<<absDataPtr->action
                 <<"  x:"<<absDataPtr->ax
                <<"  y:"<<absDataPtr->ay
                  ;
            absDataPtr++;
        }
    }
    return 0;
}

// 重新计算角度-飞行平板切割机
void EmbData::setCut2recalculateAngles()
{
    qDebug()<<__FUNCTION__;
    // 检查数据有效性
    if (m_embAbsData.isEmpty()) {
        qWarning() << "Data is empty.";
        return;
    }

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem* pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem* absDataPtr = pData;

    QByteArray cutAbsData;
    cutAbsData.clear();
    int newstepnum = 0;
    DsAbsItem absItem={};

    for (int i = 0; i < stepsize; ++i)
    {
        if(i == 0)
        {
            memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
            newstepnum++;
            cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
        }
        else if(i == stepsize-1)
        {
            memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
            absItem.ar = (pData+stepsize-1)->ar;
            newstepnum++;
            cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
        }
        else
        {
            memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
            absItem.ar = calculateAngles(absItem.ax, absItem.ay,(absDataPtr-1)->ax, (absDataPtr-1)->ay);
            newstepnum++;
            cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
        }
        absDataPtr++;
    }

    absItem.ctrl = DATA_NULL;//增加结束点
    newstepnum++;
    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));

    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    return;
}

// 重新计算角度-飞行平板切割机2
void EmbData::setCut2recalculateAngles2()
{
    qDebug()<<__FUNCTION__;

    // 检查数据有效性
    if (m_embAbsData.isEmpty()) {
        qWarning() << "Data is empty.";
        return;
    }

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem* pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem* absDataPtr = pData;

    QByteArray cutAbsData;
    cutAbsData.clear();
    int newstepnum = 0;
    DsAbsItem absItem={};

    for (int i = 0; i < stepsize; ++i)
    {
        memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));

        if(i == 0)
        {
            newstepnum++;
            cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
        }
        else if(i == stepsize-1)
        {
            newstepnum++;
            cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
        }
        else
        {
            absItem.ar = calculateAngles(absItem.ax, absItem.ay,(absDataPtr-1)->ax, (absDataPtr-1)->ay);
            newstepnum++;
            cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
        }
        absDataPtr++;
    }

    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    return;
}

// 增加圆刀数据两端补偿
// 输入
//#define     CUT_RNF_COMP          (1000)                // 圆刀退刀补偿 ,单位0.01mm
int EmbData:: setCut2AddCutterComption()
{
    qDebug()<<__FUNCTION__;
    int cutRnfComp = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutRnfComp").toInt();
    if(cutRnfComp == 0)
    {
        return -1;
    }

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步

    if (0)
    {
        pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
        absDataPtr = pData;  //中间数据针步

        for (int j = 0; j < stepsize;j++)
        {
            qDebug()<<"123 idx:"<<j
                   <<"  ctrl:"<<absDataPtr->ctrl
                  <<"  x:"<<absDataPtr->ax
                 <<"  y:"<<absDataPtr->ay
                   ;
            absDataPtr++;
        }
    }

    bool isCuttingData = false;//上一针是切割数据

    DsAbsItem absItem;

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();

    absDataPtr = pData;  //中间数据针步
    for (int j = 0; j < stepsize;j++)
    {
        if ((j == 0) ||
                (absDataPtr->ctrl == DATA_NULL) ||
                (absDataPtr->ctrl == DATA_END) ||
                (absDataPtr->ctrl == DATA_ANGLE_OLD) ||        // 拐点
                (absDataPtr->ctrl == DATA_OFFSET)    ||        // 偏移
                (absDataPtr->ctrl == DATA_DRAWING) )       // 画笔
        {// 找到起点
            isCuttingData = false;
            memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
            newstepnum++;
            cutAbsData.append((char*)(absDataPtr), sizeof(DsAbsItem));
        }
        else
        {
            if (!isCuttingData)//上一针不是切割数据
            {// 增加起始补偿数据
                isCuttingData = true; // 起始点标志

                double crt = cutRnfComp*1.0;              // 补偿量
                double r = (absDataPtr->ar) / 10000.0;      // 角度(弧度制)
                double cosr = (double)qCos(r);
                double sinr = (double)qSin(r);
                double tx = cosr * (crt*1.0);
                double ty = sinr * (crt*1.0);

                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));

                absItem.ax -= tx;
                absItem.ay -= ty;
                absItem.ar = calculateAngles(absItem.ax,absItem.ay,(absDataPtr-1)->ax,(absDataPtr-1)->ay);

                newstepnum++;
                cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
            }

            // 复制当前针步
            memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
            newstepnum++;
            cutAbsData.append((char*)(absDataPtr), sizeof(DsAbsItem));

            if (isCuttingData) //上一针是切割数据
            {// 增加收尾补偿数据
                absDataPtr++;
                if ((absDataPtr->ctrl == DATA_NULL) ||
                        (absDataPtr->ctrl == DATA_END) ||
                        (absDataPtr->ctrl == DATA_ANGLE_OLD) ||        // 拐点
                        (absDataPtr->ctrl == DATA_OFFSET)    ||        // 偏移
                        (absDataPtr->ctrl == DATA_DRAWING))        // 画笔
                {
                    absDataPtr--;

                    double crt = cutRnfComp*1.0;              // 补偿量
                    double r = (absDataPtr->ar) / 10000.0;      // 角度(弧度制)
                    double cosr = (double)qCos(r);
                    double sinr = (double)qSin(r);
                    double tx = cosr * (crt*1.0);
                    double ty = sinr * (crt*1.0);

                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));

                    absItem.ax += tx;
                    absItem.ay += ty;
                    absItem.ar = calculateAngles(absItem.ax,absItem.ay,(absDataPtr-1)->ax,(absDataPtr-1)->ay);

                    newstepnum++;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));

                }
                else
                {
                    absDataPtr--;
                }
            }
        }
        absDataPtr++;
    }


    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    return 0;
}

// 增加圆刀补偿数据
//yct实现
int EmbData::setCut2AddCutterComption2()
{
    qDebug()<<__FUNCTION__;
    //补偿长度
    int cutRnfComp = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutRnfComp").toInt();
    double comDistance = cutRnfComp*1.0 ;              // 补偿量  //切割两端补偿

    //垂直补偿
    int cutVertComp = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutVertComp").toInt();
    double comDistanceVert = cutVertComp*1.0 ;              // 补偿量  //切割垂直补偿
    comDistanceVert = 0;//目前垂直补偿禁用，将其赋值为0 避免影响

    //补偿最大角度
    double cutCrutchAng =  g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutCrutchAng").toDouble();
    double cutMaxAng = (cutCrutchAng * PI / 180) * 10000; //转换为弧度    //拐点转角判断度数

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步

#if(0)
    pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    absDataPtr = pData;  //中间数据针步
    qDebug() << __FUNCTION__ << "PreCompensation Ptr stepsize+++++++++++++++++++++++++++++" << stepsize;
    for (int j = 0; j < stepsize;j++)
    {
        qDebug()<<"idx:"<< j <<"  x:"<<absDataPtr->ax <<"  y:"<<absDataPtr->ay  << "ar:" << absDataPtr->ar <<"  ctrl:"<< QString::number(absDataPtr->ctrl,16);;
        absDataPtr++;
    }
#endif


    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();
    absDataPtr = pData;  //中间数据针步

    DsAbsItem preAbsItem;//前一针
    int firstCutData = 0; //第一帧数据

    for (int j = 0; j < stepsize; j++)
    {
        // 复制当前针步
        DsAbsItem curAbsItem;
        memcpy(&curAbsItem,absDataPtr,sizeof(DsAbsItem));

        if((firstCutData == 0) && (curAbsItem.ctrl == DATA_RKNIFE  || curAbsItem.ctrl == DATA_SKNIFE)){
            firstCutData = 1;
        }

        DsAbsItem nextItem;
        if (j < stepsize - 1) {
            DsAbsItem * nextItemPtr = absDataPtr + 1;
            memcpy((char*)&nextItem, (char *)nextItemPtr, sizeof(DsAbsItem));
        } else {
            // 处理最后一个数据项的情况
            DsAbsItem * nextItemPtr = absDataPtr;
            memcpy((char*)&nextItem,(char *)nextItemPtr,sizeof(DsAbsItem));
        }

        double dr = qAbs(nextItem.ar) - qAbs(curAbsItem.ar); //偏转角度
        dr = qAbs(dr);

        //倒数第一针 //结尾补偿
        if((j == stepsize - 1) && isCutCtrl(curAbsItem.ctrl)){
            cutDataEndCompensate(curAbsItem,preAbsItem,comDistance);
            cutDataVertCut(curAbsItem, comDistanceVert, cutAbsData,newstepnum);
        }
        else if(j == 0){//第一针不处理
        }
        //结尾补偿
        else if( isCutCtrl(curAbsItem.ctrl)
                 && (nextItem.ctrl == DATA_NULL || nextItem.ctrl == DATA_END
                     || nextItem.ctrl == DATA_ANGLE_OLD || nextItem.ctrl == DATA_OFFSET )
                 //&& (curAbsItem.ax != nextItem.ax && curAbsItem.ay != nextItem.ay )
                 && 1)
        {
            cutDataEndCompensate(curAbsItem,preAbsItem,comDistance);
            cutDataVertCut(curAbsItem, comDistanceVert, cutAbsData,newstepnum);
        }
        //开头补偿
        else if (isCutCtrl(nextItem.ctrl)
                 && (curAbsItem.ctrl == DATA_NULL || curAbsItem.ctrl == DATA_END
                     || curAbsItem.ctrl == DATA_ANGLE_OLD || curAbsItem.ctrl == DATA_OFFSET )
                 //&& (curAbsItem.ax != nextItem.ax && curAbsItem.ay != nextItem.ay )
                 && 1)
        {
            cutDataStartCompensate(curAbsItem,preAbsItem,nextItem,comDistance);
        }

#if(1)
        //切割数据中大角度分割
        else if((isCutCtrl(preAbsItem.ctrl))
                && (isCutCtrl(curAbsItem.ctrl))
                && (dr > cutMaxAng)
                && (comDistance > 0.0)
                && ((curAbsItem.ay != nextItem.ay) || (curAbsItem.ax != nextItem.ax))
                && 1)
        {
            //qDebug()<< " cur double end :" << j << "x :" << curAbsItem.ax << "y :" << curAbsItem.ay << "dr:" << dr << "cutMaxAng :" <<cutMaxAng << " ctrl" <<QString::number(curAbsItem.ctrl,16);
            //前一个针步延长
            DsAbsItem endExItem = curAbsItem;; //结尾延长
            cutDataEndCompensate(endExItem,preAbsItem,comDistance);
            //添加结尾补偿针
            newstepnum++;
            cutAbsData.append((char*)(&endExItem), sizeof(DsAbsItem));

            //后一个针步起点补偿
            curAbsItem.ctrl = DATA_OFFSET;
            cutDataStartCompensate(curAbsItem,preAbsItem,nextItem,comDistance);
        }
#endif
        newstepnum++;
        cutAbsData.append((char*)(&curAbsItem), sizeof(DsAbsItem));//添加这一针
        preAbsItem = curAbsItem;//记录针
        absDataPtr++;
    }

    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数
    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;
    return 0;
}

// 增加圆刀补偿数据
int EmbData::setCut2AddCutterComption22()
{
    qDebug()<<__FUNCTION__;
    //补偿长度
    int cutRnfComp = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutRnfComp").toInt();
    double comDistance = cutRnfComp*1.0 ;              // 补偿量  //切割两端补偿

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();
    absDataPtr = pData;  //中间数据针步

    DsAbsItem preAbsItem;//前一针
    int firstCutData = 0; //第一帧数据

    // 数据区
    double minY = DBL_MAX;  // Y最小值
    double maxY = -DBL_MAX; // Y最大值

    for(int j = 0; j <stepsize; j++)
    {
        if (minY > absDataPtr->ay)
        {
            minY = absDataPtr->ay;
        }
        if (maxY < absDataPtr->ay)
        {
            maxY = absDataPtr->ay;
        }
        absDataPtr++;
    }

    absDataPtr = pData;//复位指针
    for (int j = 0; j < stepsize; j++)
    {
        // 复制当前针步
        DsAbsItem curAbsItem;
        memcpy(&curAbsItem,absDataPtr,sizeof(DsAbsItem));

        if((firstCutData == 0) && (curAbsItem.ctrl == DATA_RKNIFE  || curAbsItem.ctrl == DATA_SKNIFE)){
            firstCutData = 1;
        }

        DsAbsItem nextItem;
        if (j < stepsize - 1) {
            DsAbsItem * nextItemPtr = absDataPtr + 1;
            memcpy((char*)&nextItem, (char *)nextItemPtr, sizeof(DsAbsItem));
        } else {
            // 处理最后一个数据项的情况
            DsAbsItem * nextItemPtr = absDataPtr;
            memcpy((char*)&nextItem,(char *)nextItemPtr,sizeof(DsAbsItem));
        }

        double dr = qAbs(nextItem.ar) - qAbs(curAbsItem.ar); //偏转角度
        dr = qAbs(dr);

        //倒数第一针 //结尾补偿
        if((j == stepsize - 1) && isCutCtrl(curAbsItem.ctrl)){
            cutDataEndCompensate2(curAbsItem,preAbsItem,comDistance,maxY,minY);
        }
        else if(j == 0){//第一针不处理
        }
        //结尾补偿
        else if( isCutCtrl(curAbsItem.ctrl)
                 && (nextItem.ctrl == DATA_NULL || nextItem.ctrl == DATA_END
                     || nextItem.ctrl == DATA_ANGLE_OLD || nextItem.ctrl == DATA_OFFSET )
                 && 1)
        {
            cutDataEndCompensate2(curAbsItem,preAbsItem,comDistance,maxY,minY);
        }
        //开头补偿
        else if (isCutCtrl(nextItem.ctrl)
                 && (curAbsItem.ctrl == DATA_NULL || curAbsItem.ctrl == DATA_END
                     || curAbsItem.ctrl == DATA_ANGLE_OLD || curAbsItem.ctrl == DATA_OFFSET )
                 && 1)
        {
            cutDataStartCompensate2(curAbsItem,preAbsItem,nextItem,comDistance,maxY,minY);
        }

        newstepnum++;
        cutAbsData.append((char*)(&curAbsItem), sizeof(DsAbsItem));//添加这一针
        preAbsItem = curAbsItem;//记录针
        absDataPtr++;
    }

    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数
    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;
    return 0;
}

// 排序&组成新数据
int EmbData:: setCut2SortNewData()
{
    qDebug()<<__FUNCTION__;
    bool enableBrush = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutEnableBrush").toBool();      // 启动画笔

    int i = 0;
    int j = 0;
    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));

    int winNum = m_winnums;         // 窗口个数

    if (m_winnums == 0)
    {// 通过数据计算窗口个数
        DsAbsItem absItem;
        DsAbsItem * absDataPtr = pData;  //中间数据针步
        for (j = 0; j < stepsize; j++)
        {
            memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
            if (winNum < absItem.action)
            {
                winNum = absItem.action;
            }
            absDataPtr++;
        }
        winNum++;
    }
    qDebug()<<winNum;

    // 数据分类
    QVector<QVector<QByteArray>> penVisited(winNum, QVector<QByteArray>(0));            // 画笔数据
    QVector<QVector<QByteArray>> cutShakeVisited(winNum, QVector<QByteArray>(0));       // 震刀数据
    QVector<QVector<QByteArray>> cutRountVisited(winNum, QVector<QByteArray>(0));       // 圆刀数据

    int begFlg = 0;

    QByteArray ary;
    DsAbsItem absItem;
    DsAbsItem * absDataPtr = pData;  //中间数据针步

    for (j = 0; j < stepsize; j++)
    {
        if ((absDataPtr->ctrl == DATA_NULL) ||
                (absDataPtr->ctrl == DATA_END) ||
                (absDataPtr->ctrl == DATA_ANGLE_OLD) ||
                (absDataPtr->ctrl == DATA_OFFSET))
        {
            begFlg = 0;
        }
        else if(absDataPtr->ctrl == DATA_RKNIFE)
        {// 圆刀数据
            if (begFlg == 0)
            {// 线段起始位置加入拐点标志
                begFlg = 1;         // 起始点标志
                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));

                absItem.ctrl = DATA_ANGLE_OLD;
                ary.clear();
                ary.append((char*)&absItem, sizeof(DsAbsItem));
                cutRountVisited[absItem.action].append(ary);
            }

            {// 赋值当前数据
                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                ary.clear();
                ary.append((char*)&absItem, sizeof(DsAbsItem));
                cutRountVisited[absItem.action].append(ary);
            }
        }
        else if(absDataPtr->ctrl == DATA_DRAWING)
        {// 画笔数据
            if (enableBrush)
            {// 增加画笔数据
                if (begFlg == 0)
                {// 线段起始位置加入拐点标志
                    begFlg = 1;         // 起始点标志
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));

                    absItem.ctrl = DATA_ANGLE_OLD;
                    ary.clear();
                    ary.append((char*)&absItem, sizeof(DsAbsItem));
                    penVisited[absItem.action].append(ary);
                }

                {// 赋值当前数据
                    memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                    ary.clear();
                    ary.append((char*)&absItem, sizeof(DsAbsItem));
                    penVisited[absItem.action].append(ary);
                }
            }
        }
        else if(absDataPtr->ctrl == DATA_SKNIFE)
        {// 振刀数据
            if (begFlg == 0)
            {// 线段起始位置加入拐点标志
                begFlg = 1;         // 起始点标志
                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));

                absItem.ctrl = DATA_ANGLE_OLD;
                ary.clear();
                ary.append((char*)&absItem, sizeof(DsAbsItem));
                cutShakeVisited[absItem.action].append(ary);
            }

            {// 赋值当前数据
                memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
                ary.clear();
                ary.append((char*)&absItem, sizeof(DsAbsItem));
                cutShakeVisited[absItem.action].append(ary);
            }
        }
        absDataPtr++;
    }

    // 数据排序
    optimizationOrder(cutRountVisited,winNum);
    optimizationOrder(cutShakeVisited,winNum);
    optimizationOrder(penVisited,winNum);

    if (1)
    {// 如果某个窗口内没有数据,则在窗口内增加一个画笔数据
        int cutXWindow = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutXLengh").toInt();
        if(cutXWindow == 0)
        {
            cutXWindow = 500000;
        }

        double xWin = (cutXWindow*4/10);     // 窗口宽度

        double xminPos = DBL_MAX;  // X最小值
        double yminPos = DBL_MAX;  // Y最小值
        absDataPtr = pData;  //中间数据针步

        for(int j = 0; j <stepsize; j++)
        {// 求有效数据的最小值
            if ((absDataPtr->ctrl == DATA_RKNIFE) || (absDataPtr->ctrl == DATA_SKNIFE))
            {
                if (xminPos > absDataPtr->ax)
                {
                    xminPos = absDataPtr->ax;
                }
                if (yminPos > absDataPtr->ay)
                {
                    yminPos = absDataPtr->ay;
                }
            }
            else if ((absDataPtr->ctrl == DATA_DRAWING) && (enableBrush))
            {
                if (xminPos > absDataPtr->ax)
                {
                    xminPos = absDataPtr->ax;
                }
                if (yminPos > absDataPtr->ay)
                {
                    yminPos = absDataPtr->ay;
                }
            }
            absDataPtr++;
        }

        if (yminPos != DBL_MAX)
        {// 如果某个窗口内没有数据,则在ymin的位置增加一个画笔数据
            addPenData(penVisited,cutRountVisited,cutShakeVisited,winNum,xWin,xminPos,yminPos);
        }
    }

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    // 合并数据
    cutAbsData.clear();

    for (i = 0; i<winNum;i++)
    {
        int stepnumPen = penVisited[i].size();   // 画笔数据
        if (stepnumPen > 0)
        {
            newstepnum += stepnumPen;
            for (j = 0;j<stepnumPen;j++)
            {
                cutAbsData.append(penVisited[i][j]);
            }
        }

        int stepCutShake = cutShakeVisited[i].size();   // 切刀数据
        if (stepCutShake > 0)
        {
            newstepnum += stepCutShake;
            for (j = 0;j < stepCutShake;j++)
            {
                cutAbsData.append(cutShakeVisited[i][j]);
            }
        }

        int stepCutRound = cutRountVisited[i].size();   // 圆刀数据
        if (stepCutRound > 0)
        {
            newstepnum += stepCutRound;
            for (j = 0;j < stepCutRound;j++)
            {
                cutAbsData.append(cutRountVisited[i][j]);
            }
        }
    }

    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头
    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    return 0;
}

// 两窗口之间单独设定补偿值
void EmbData:: setCut2WinComp()
{
    qDebug()<<__FUNCTION__;
    int compVal = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutEnableBrush").toBool();      // 启动画笔
    compVal = 10000;

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return;
    }

    //DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    //DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));


}

//增加偏移数据
int EmbData::setCut2AddOffsetData()
{
    qDebug() << __FUNCTION__;
    int cutLineStp = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutLineStp").toInt();
    if (cutLineStp == 0) {
        cutLineStp = 3000;
    }

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead)) {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0) {
        qDebug("absdat dataBegin err");
        return -1;
    }

    int stepsize = datasize / sizeof(DsAbsItem);
    if (stepsize <= 0) {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead* pHead = (DataDs16FileHead*)(m_embAbsData.data());
    DsAbsItem* pData = (DsAbsItem*)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem* absDataPtr = pData;

    QByteArray cutAbsData;
    cutAbsData.clear();
    int newstepnum = 0;
    DsAbsItem absItem;

    // 数据区
    double begX = 0;// 起始点
    double begY = 0;
    for (int j = 0; j < stepsize; j++)
    {
        memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
        if (j == 0)
        {
            newstepnum++;
            cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
        }
        else if (absItem.ctrl == DATA_ANGLE_OLD)
        {// 分割偏移数据
            absItem.ctrl = DATA_OFFSET;
            absItem.attr = 0;
            if ((begX != absDataPtr->ax) || (begY != absDataPtr->ay))
            {
                newstepnum += splittingLine
                        (begX, begY, absDataPtr->ax, absDataPtr->ay,
                         cutLineStp, cutLineStp,
                         cutAbsData, absItem);   // 分割直线
            }
        }
        else
        {
            absItem.attr = 0;
            newstepnum++;
            cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
        }

        begX = absItem.ax;
        begY = absItem.ay;
        absDataPtr++;
    }

    // 更新文件头并替换数据
    pHead->dataSize = newstepnum * sizeof(DsAbsItem);
    pHead->itemNums = newstepnum;
    cutAbsData.insert(0, (char*)pHead, sizeof(DataDs16FileHead));
    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    return 0;
}

// 整理数据(在两种不同数据中增加拐点,同时剔除两个拐点中只有一个数据的情况)
int EmbData:: setCut2ArrangeData()
{
    qDebug()<<__FUNCTION__;

    bool delEdge = g_pSettings->readFromIniFile("FlatPanelAlgorithm/delEdge").toBool();
    if(!delEdge)
    {
        return -1;
    }

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步
    DsAbsItem absItem;

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();

    DsAbsItem* nextItem = NULL;

    absDataPtr = pData;  //中间数据针步
    u8 ctrlBuf = 0;     // 当前控制字节
    u8 ctrlPrev = 0;	// 前一个控制字节

    for(int j = 0; j <stepsize; j++)
    {
        memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));

        if ((j == 0) && (absItem.ctrl != DATA_ANGLE_OLD))
        {// 如果第一个数据不是拐点,则增加一个拐点数据
            ctrlBuf = absItem.ctrl;
            ctrlPrev = DATA_ANGLE_OLD;
            absItem.ctrl = DATA_ANGLE_OLD;
            cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));        // 增加一个拐点数据
            newstepnum++;

            absItem.ctrl = ctrlBuf;
        }

        if (ctrlPrev == DATA_ANGLE_OLD)
        {
            if (absItem.ctrl == DATA_ANGLE_OLD)
            {// 如果当前点和前一个点都是拐点,则不处理当前的拐点.
                absDataPtr++;
                continue;
            }
            else    //if (absItem.ctrl != DATA_ANGLE_OLD)
            {
                nextItem = &pData[j+1];         // 获取后继节点
                if (absItem.ctrl != nextItem->ctrl)
                {// 如果当前数据是起点,判断后续数据是否和当前数据类型相同.如果不相同则不处理当前数据
                    absDataPtr++;
                    continue;
                }
                else
                {// 数据正常,保存当前数据
                    ctrlPrev = absItem.ctrl;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                    newstepnum++;
                }
            }
        }
        else //if (ctrlPrev != DATA_ANGLE_OLD)
        {
            nextItem = &pData[j+1];         // 获取后继节点
            if ((absItem.ctrl != nextItem->ctrl) &&
                    (absItem.ctrl != DATA_ANGLE_OLD) &&
                    (nextItem->ctrl != DATA_ANGLE_OLD) &&
                    1 )
            {// 如果连续的两个数据间,没有拐点数据,则增加一个拐点数据
                // 保存当前数据
                cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                newstepnum++;

                // 增加一个拐点
                ctrlPrev = DATA_ANGLE_OLD;
                absItem.ctrl = DATA_ANGLE_OLD;
                cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                newstepnum++;

                if ((absItem.ax != nextItem->ax) ||
                        (absItem.ay != nextItem->ay) ||
                        0)
                {// 如果下一个点的起点与当前点坐标不一样.给下一个数据增加起始点数据
                    absItem.ctrl = nextItem->ctrl;
                    absItem.action = nextItem->action;
                    absItem.attr = nextItem->attr;
                    absItem.ar = nextItem->ar;

                    ctrlPrev = absItem.ctrl;
                    cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                    newstepnum++;
                }
            }
            else
            {// 正常数据,保存当前数据
                ctrlPrev = absItem.ctrl;
                cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
                newstepnum++;
            }
        }
        absDataPtr++;
    }

    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    return 0;
}

// 新版排序后整理数据
int EmbData:: setCut2ArrangeDataForNew()
{
    qDebug()<<__FUNCTION__;

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步
    DsAbsItem absItem;

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();

    absDataPtr = pData;  //中间数据针步
    DsAbsItem* nextItem = NULL;
    DsAbsItem* nextItem2 = NULL;

    bool offsetflag = false;

    for(int j = 0; j <stepsize; j++)
    {
        memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));

        if(j==stepsize-1)//赋值后一节点数据
        {
            nextItem = absDataPtr;
        }else
        {
            nextItem = absDataPtr+1;
        }

        if(j==stepsize-1)//赋值后2节点数据
        {
            nextItem2 = absDataPtr;
        }else
        {
            nextItem2 = absDataPtr+2;
        }

        if(absItem.ctrl==DATA_ANGLE_OLD&&
                nextItem->ctrl==DATA_RKNIFE&&
                nextItem2->ctrl==DATA_ANGLE_OLD&&
                nextItem->ax==absItem.ax&&
                nextItem->ay==absItem.ay&&
                nextItem2->ax==absItem.ax&&
                nextItem2->ay==absItem.ay)
        {
            offsetflag = true;
            absDataPtr++;
            continue;
        }

        if(offsetflag)
        {
            absDataPtr++;
            offsetflag=false;
            continue;
        }

        //if (absItem.ctrl == DATA_ANGLE_OLD)
        //{// 如果当前点和前一个点都是拐点,则不处理当前的拐点.
        //    absItem.ar = (absDataPtr+1)->ar;
        //}

        newstepnum++;
        cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));

        absDataPtr++;
    }

    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    return 0;
}

// 整理画笔数据
int EmbData:: setCut2ArrangeDataForPen()
{
    qDebug()<<__FUNCTION__;

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步
    DsAbsItem absItem;

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();

    absDataPtr = pData;  //中间数据针步
    DsAbsItem* preItem = NULL;
    DsAbsItem* nextItem = NULL;

    bool offsetFlag = false;

    for(int j = 0; j <stepsize; j++)
    {
        memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));

        if(j==stepsize-1)//赋值后一节点数据
        {
            nextItem = absDataPtr;
        }else
        {
            nextItem = absDataPtr+1;
        }

        if(j==0)//赋值前一节点数据
        {
            preItem = absDataPtr;
        }else
        {
            preItem = absDataPtr-1;
        }

        //判断异常数据 设置标记
        if(preItem->ctrl==DATA_DRAWING&&
                absItem.ctrl==DATA_ANGLE_OLD&&
                nextItem->ctrl==DATA_DRAWING&&
                preItem->ax==absItem.ax&&
                preItem->ay==absItem.ay&&
                nextItem->ax==absItem.ax&&
                nextItem->ay==absItem.ay)
        {
            offsetFlag = true;
        }
        else if(offsetFlag)
        {
            offsetFlag = false;
            absDataPtr++;
            continue;
        }

        newstepnum++;
        cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));

        absDataPtr++;
    }

    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    return 0;
}

// 整理切刀数据
int EmbData:: setCut2ArrangeDataForKnife()
{
    qDebug()<<__FUNCTION__;

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步
    DsAbsItem absItem;

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();

    absDataPtr = pData;  //中间数据针步
    DsAbsItem* preItem = NULL;

    for(int j = 0; j <stepsize; j++)
    {
        memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));

        if(j==0)//赋值前一节点数据
        {
            preItem = absDataPtr;
        }else
        {
            preItem = absDataPtr-1;
        }

        //判断异常数据 设置标记
        if(preItem->ctrl==DATA_RKNIFE&&
                absItem.ctrl==DATA_OFFSET&&
                preItem->ax==absItem.ax&&
                preItem->ay==absItem.ay)
        {
            absDataPtr++;
            continue;
        }

        newstepnum++;
        cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));

        absDataPtr++;
    }

    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    return 0;
}

// 新版排序后整理数据 此函数旨在：去除原地画一点/切一点的坐标
int EmbData:: setCut2ArrangeDataForNewPenAndKnife()
{
    qDebug()<<__FUNCTION__;

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步
    DsAbsItem absItem;

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();

    absDataPtr = pData;  //中间数据针步
    DsAbsItem* preItem = NULL;

    for(int j = 0; j <stepsize; j++)
    {
        memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));

        if(j==0)//赋值前一节点数据
        {
            preItem = absDataPtr;
        }else
        {
            preItem = absDataPtr-1;
        }

        if( j != 0 &&
                (preItem->ctrl==DATA_DRAWING||preItem->ctrl==DATA_OFFSET)&&
                (absItem.ctrl==DATA_DRAWING)&&
                preItem->ax==absItem.ax&&
                preItem->ay==absItem.ay)
        {
            absDataPtr++;
            continue;
        }

        newstepnum++;
        cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));

        absDataPtr++;
    }

    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    return 0;
}

// 剔除数据(剔除两个拐点中只有一个数据的情况，直接去除后两个节点)
int EmbData:: setCut2RemoveErroData()
{
    qDebug()<<__FUNCTION__;

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步
    DsAbsItem absItem;

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();

    DsAbsItem* nextItem = NULL;
    DsAbsItem* preItem = NULL;
    //bool conFlag = false;

    for(int j = 0; j <stepsize; j++)
    {
        memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));

        if(j==stepsize-1)//赋值后一节点数据
        {
            nextItem=absDataPtr;
        }else
        {
            nextItem=absDataPtr+1;
        }

        if(j==0)//赋值前一节点数据
        {
            preItem = absDataPtr;
        }else
        {
            preItem = absDataPtr-1;
        }

        if(preItem->ctrl==DATA_RKNIFE&&absItem.ctrl==DATA_ANGLE_OLD&&nextItem->ctrl==DATA_RKNIFE)
        {
            absItem.ar = nextItem->ar;
        }

        cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
        newstepnum++;
        absDataPtr++;
    }

    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    return 0;
}

// 重叠线段函数-辅助函数：剔除异常数据(剔除 偏移点-切割点 x/y相同的情况)
int EmbData:: setCut2RemoveErroData2()
{
    qDebug()<<__FUNCTION__;

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步
    DsAbsItem absItem;

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();

    DsAbsItem* preItem = NULL;

    for(int j = 0; j <stepsize; j++)
    {
        memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));

        if(j==0)//赋值前一节点数据
        {
            preItem = absDataPtr;
        }else
        {
            preItem = absDataPtr-1;
        }

        if(preItem->ctrl==DATA_OFFSET &&
                preItem->ax == absItem.ax &&
                preItem->ay == absItem.ay &&
                absItem.ctrl== DATA_RKNIFE)
        {
            absDataPtr++;
            continue;
        }

        cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
        newstepnum++;
        absDataPtr++;
    }

    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    return 0;
}

// 删除上下边界的数据
int EmbData:: setCut2DelEdgeData()
{
    qDebug()<<__FUNCTION__;

    bool delEdge = g_pSettings->readFromIniFile("FlatPanelAlgorithm/delEdge").toBool();//启用边界消除
    if(!delEdge)
    {
        return -1;
    }

    double deledgeval = 1.0*(g_pSettings->readFromIniFile("FlatPanelAlgorithm/DelEdgeValue").toInt());//边界消除误差
    if(deledgeval<=0)
    {
        deledgeval=200.0;
    }

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;  //中间数据针步
    DsAbsItem absItem;

    int newstepnum = 0;
    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();

    // 数据区
    double minY = DBL_MAX;  // Y最小值
    double maxY = -DBL_MAX; // Y最大值

    for(int j = 0; j <stepsize; j++)
    {
        if (minY > absDataPtr->ay)
        {
            minY = absDataPtr->ay;
        }
        if (maxY < absDataPtr->ay)
        {
            maxY = absDataPtr->ay;
        }
        absDataPtr++;
    }

    qDebug()<<"maxY:"<<maxY<<"minY:"<<minY;

    DsAbsItem* prevItem = NULL;
    DsAbsItem* nextItem = NULL;
    absDataPtr = pData;  //中间数据针步

    for(int j = 0; j <stepsize; j++)
    {
        memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));
        if ((j == 0) || (j == stepsize-1))
        {
            absDataPtr++;
            continue;
        }
        else if ((absItem.ctrl == DATA_RKNIFE) ||
                 (absItem.ctrl == DATA_SKNIFE) ||
                 (absItem.ctrl == DATA_DRAWING) ||
                 0)
        {
            prevItem = &pData[j-1];         // 获取前驱节点（循环处理）
            nextItem = &pData[j+1];         // 获取后继节点

            if ((absItem.ctrl == prevItem->ctrl) &&
                    (absItem.ctrl == nextItem->ctrl) &&
                    1 )
            {// 将Y在最上边和最下面的数据删除
                if (std::fabs(absItem.ay - minY) <= deledgeval)
                {// 当相邻三个点的Y都是最小值时.剔除中间一个点(当前点)的数据
                    if ((std::fabs(prevItem->ay - minY) <= deledgeval) &&
                            (std::fabs(nextItem->ay - minY) <= deledgeval) &&
                            1 )
                    {
                        absItem.ctrl = DATA_OFFSET;
                    }
                }
                else if (std::fabs(absItem.ay - maxY) <= deledgeval)
                {// 当相邻三个点的Y都是最大值时.剔除中间一个点(当前点)的数据
                    if ((std::fabs(prevItem->ay - maxY) <= deledgeval) &&
                            (std::fabs(nextItem->ay - maxY) <= deledgeval) &&
                            1 )
                    {
                        absItem.ctrl = DATA_OFFSET;
                    }
                }
            }
            else if (prevItem->ctrl == DATA_ANGLE_OLD||prevItem->ctrl == DATA_OFFSET)
            {// 数据起始点
                if (std::fabs(absItem.ay - minY) <= deledgeval)
                {// 当相邻三个点的Y都是最小值时.剔除中间一个点(当前点)的数据
                    if (//(std::fabs(prevItem->ay - minY) < deledgeval) &&
                            (std::fabs(nextItem->ay - minY) <= deledgeval) &&
                            1 )
                    {
                        absItem.ctrl = DATA_OFFSET;
                    }
                }
                else if (std::fabs(absItem.ay - maxY) <= deledgeval)
                {// 当相邻三个点的Y都是最小值时.剔除中间一个点(当前点)的数据
                    if (//(std::fabs(prevItem->ay - maxY) < deledgeval) &&
                            (std::fabs(nextItem->ay - maxY) <= deledgeval) &&
                            1 )
                    {
                        absItem.ctrl = DATA_OFFSET;
                    }
                }
            }
            else if (nextItem->ctrl == DATA_ANGLE_OLD||nextItem->ctrl == DATA_OFFSET)
            {// 数据结束点
                if (std::fabs(absItem.ay - minY) <= deledgeval)
                {// 当相邻三个点的Y都是最小值时.剔除中间一个点(当前点)的数据
                    if ((std::fabs(prevItem->ay - minY) <= deledgeval) &&
                            // (std::fabs(nextItem->ay - minY) < deledgeval) &&
                            1 )
                    {
                        absItem.ctrl = DATA_OFFSET;
                    }
                }
                else if (std::fabs(absItem.ay - maxY) <= deledgeval)
                {// 当相邻三个点的Y都是最小值时.剔除中间一个点(当前点)的数据
                    if ((std::fabs(prevItem->ay - maxY) <= deledgeval) &&
                            // (std::fabs(nextItem->ay - maxY) < deledgeval) &&
                            1 )
                    {
                        absItem.ctrl = DATA_OFFSET;
                    }
                }
            }
        }

        cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
        newstepnum++;
        absDataPtr++;
    }

    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    return 0;
}

// 增加距离数据
// 用于存放当前窗口中,每个点距离最左边数据的距离.单位10mm,存放在attr中
int EmbData:: setCut2AddDistanData()
{
    qDebug()<<__FUNCTION__;

    int size = m_embAbsData.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    DataDs16FileHead * pHead =  (DataDs16FileHead *)(m_embAbsData.data());
    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData+(stepsize-1);  //中间数据针步

    DsAbsItem absItem;

    int newstepnum = 0;
    QByteArray cutAbsDataRes;      // 切割临时数据
    cutAbsDataRes.clear();

    // 数据区
    double minX = S32_MAX;        // X最小值
    WORD curWin = S16_MAX;      // 当前窗口
    int dis = 0;


    for (int j = (stepsize-1); j >=0; j--)
    {
        memcpy(&absItem,absDataPtr,sizeof(DsAbsItem));

        if ((absItem.ctrl == DATA_RKNIFE) ||
                (absItem.ctrl == DATA_SKNIFE) ||
                (absItem.ctrl == DATA_DRAWING) ||
                (absItem.ctrl == DATA_OFFSET) ||
                0)
        {// 圆刀/切刀/画笔数据
            if (curWin != absItem.action)
            {// 切换窗口
                curWin = absItem.action;
                minX = S32_MAX;
            }

            if (minX > absItem.ax)
            {// 当前窗口下,未切割的数据中X最小值
                minX = absItem.ax;
            }
            dis = (absItem.ax - minX)/ 1000;
            if (dis < 1)
            {
                dis = 1;
            }
            else if (dis > 255)
            {
                dis = 255;
            }
            absItem.attr = (u8)(dis);     // 精度10mm,最大值2550mm
            newstepnum++;
            cutAbsDataRes.append((char*)(&absItem), sizeof(DsAbsItem));
        }

        absDataPtr--;
    }

    QByteArray cutAbsData;      // 切割临时数据
    cutAbsData.clear();

    int stepResNums = cutAbsDataRes.size()/sizeof(DsAbsItem);
    DsAbsItem * absDataPtrRes = (DsAbsItem *)(cutAbsDataRes.data());
    absDataPtrRes +=(stepResNums-1);  //中间数据针步

    for(int j = (newstepnum-1); j >=0; j--)
    {
        memcpy(&absItem,absDataPtrRes,sizeof(DsAbsItem));
        cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));
        absDataPtrRes--;
    }

    ////结束码
    //absItem.ctrl = DATA_NULL;
    //newstepnum++;
    //cutAbsData.append((char*)(&absItem), sizeof(DsAbsItem));

    pHead->dataSize = newstepnum*sizeof(DsAbsItem);     // 数据字节数
    pHead->itemNums = newstepnum;                       // 数据项个数

    cutAbsData.insert(0,(char*)pHead,sizeof(DataDs16FileHead));  // 插入文件头

    m_embAbsData.clear();
    m_embAbsData = cutAbsData;
    m_editedflag = 1;

    return 0;
}

// 辅助函数：判断线段方向
bool isAscending(const LineSegment& seg, bool isHorizontal) {
    if (isHorizontal) {
        return seg.a1.ax < seg.a2.ax;
    } else {
        return seg.a1.ay < seg.a2.ay;
    }
}
// 判断线段是否为水平方向
bool isHorizontal(const LineSegment& seg)
{
    //通过比较 X 方向和 Y 方向的变化量，判断线段更接近于水平/垂直
    return abs(seg.a2.ax - seg.a1.ax) > abs(seg.a2.ay - seg.a1.ay);
}
// 辅助函数：判断两个双精度数在容差范围内是否相等
bool almostEqual(double a, double b, double tolerance)
{
    return std::abs(a - b) <= tolerance;
}
// 判断两条线段是否平行且重叠的函数，允许一定的误差
bool areParallelAndOverlapping(const LineSegment& seg1, const LineSegment& seg2)
{
    double angleTolerance = 1e-3;

    double distanceTolerance = g_pSettings->readFromIniFile("FlatPanelAlgorithm/ORVALUE").toDouble();//重叠消除误差
    if(distanceTolerance<=0)
    {
        distanceTolerance = 100;
    }
    // 计算方向向量（保持ax/ay字段）
    const int dx1 = seg1.a2.ax - seg1.a1.ax;
    const int dy1 = seg1.a2.ay - seg1.a1.ay;
    const int dx2 = seg2.a2.ax - seg2.a1.ax;
    const int dy2 = seg2.a2.ay - seg2.a1.ay;

    // 计算叉积判断是否平行，允许一定的角度误差
    const double cross = dx1 * dy2 - dy1 * dx2;
    if (std::abs(cross) > angleTolerance) return false;

    // 计算直线方程参数 (A * x + B * y + C = 0)
    const double A = dy1;
    const double B = -dx1;
    const double C = dx1 * seg1.a1.ay - dy1 * seg1.a1.ax;
    const double denominator = qSqrt(A * A + B * B);

    // 辅助函数计算点到直线的距离
    auto calcDistance = [&A, &B, &C, &denominator](const DsAbsItem& p) -> double {
        return std::abs(A * p.ax + B * p.ay + C) / denominator;
    };

    // 共线性检查
    if (calcDistance(seg2.a1) > distanceTolerance ||
            calcDistance(seg2.a2) > distanceTolerance)
    {
        return false;
    }

    // 判断线段方向是否接近垂直或水平，使用 almostEqual
    const bool isVertical = almostEqual(dx1, 0.0, 1e-2); // 例如, 容差设置为0.01
    const bool isHorizontal = almostEqual(dy1, 0.0, 1e-2); // 根据需要调整容差

    // 垂直线处理
    if (isVertical)
    {
        // 检查两个线段的 x 坐标是否在容差范围内
        if (!almostEqual(seg1.a1.ax, seg2.a1.ax, distanceTolerance)) return false;

        // 获取 y 值的最小和最大值
        const double yMin1 = std::min(seg1.a1.ay, seg1.a2.ay);
        const double yMax1 = std::max(seg1.a1.ay, seg1.a2.ay);
        const double yMin2 = std::min(seg2.a1.ay, seg2.a2.ay);
        const double yMax2 = std::max(seg2.a1.ay, seg2.a2.ay);

        // 检查 y 轴投影是否重叠，考虑容差
        return (yMax1 + distanceTolerance >= yMin2) &&
                (yMax2 + distanceTolerance >= yMin1);
    }
    // 水平线处理
    else if (isHorizontal)
    {
        // 检查两个线段的 y 坐标是否在容差范围内
        if (!almostEqual(seg1.a1.ay, seg2.a1.ay, distanceTolerance)) return false;

        // 获取 x 值的最小和最大值
        const double xMin1 = std::min(seg1.a1.ax, seg1.a2.ax);
        const double xMax1 = std::max(seg1.a1.ax, seg1.a2.ax);
        const double xMin2 = std::min(seg2.a1.ax, seg2.a2.ax);
        const double xMax2 = std::max(seg2.a1.ax, seg2.a2.ax);

        // 检查 x 轴投影是否重叠，考虑容差
        return (xMax1 + distanceTolerance >= xMin2) &&
                (xMax2 + distanceTolerance >= xMin1);
    }
    // 斜线处理
    else
    {
        // 根据方向选择投影轴
        const bool useXProjection = std::abs(dx1) >= std::abs(dy1);

        if (useXProjection)
        {
            const double xMin1 = std::min(seg1.a1.ax, seg1.a2.ax);
            const double xMax1 = std::max(seg1.a1.ax, seg1.a2.ax);
            const double xMin2 = std::min(seg2.a1.ax, seg2.a2.ax);
            const double xMax2 = std::max(seg2.a1.ax, seg2.a2.ax);

            // 检查 x 轴投影是否重叠，考虑容差
            return (xMax1 + distanceTolerance >= xMin2) &&
                    (xMax2 + distanceTolerance >= xMin1);
        }
        else
        {
            const double yMin1 = std::min(seg1.a1.ay, seg1.a2.ay);
            const double yMax1 = std::max(seg1.a1.ay, seg1.a2.ay);
            const double yMin2 = std::min(seg2.a1.ay, seg2.a2.ay);
            const double yMax2 = std::max(seg2.a1.ay, seg2.a2.ay);

            // 检查 y 轴投影是否重叠，考虑容差
            return (yMax1 + distanceTolerance >= yMin2) &&
                    (yMax2 + distanceTolerance >= yMin1);
        }
    }
}
// 检测线段重叠类型，加入容差判断
OverlapType checkOverlap(const LineSegment& len1, const LineSegment& len2,int maxvalue)
{
    //获取线段偏向方向 偏向x或者y
    bool len1Horizontal = isHorizontal(len1);
    bool len2Horizontal = isHorizontal(len2);

    //如果偏向方向不一致肯定不平行
    if (len1Horizontal != len2Horizontal)
        return None;

    // 使用带容差的判断平行重叠
    if(!areParallelAndOverlapping(len1, len2))
        return None;

    if (len1Horizontal)
    {
        //x方向平行 获取len1/len2最大/最小x值 使用qRound实现四舍五入
        double len1MinX = std::min(len1.a1.ax+maxvalue, len1.a2.ax+maxvalue);
        double len1MaxX = std::max(len1.a1.ax+maxvalue, len1.a2.ax+maxvalue);
        double len2MinX = std::min(len2.a1.ax+maxvalue, len2.a2.ax+maxvalue);
        double len2MaxX = std::max(len2.a1.ax+maxvalue, len2.a2.ax+maxvalue);

        // 检查是否完全重叠
        if(std::abs(len1MinX-len2MinX)<ZERO && std::abs(len1MaxX-len2MaxX)<ZERO)
            return Full;
        // 检查是否len1包含len2
        else if(len1MinX <= len2MinX && len1MaxX >= len2MaxX)
            return Contains_1;
        // 检查是否len2包含len1
        else if(len2MinX <= len1MinX  && len2MaxX >= len1MaxX)
            return Contains_2;
        // 检查是否len1、len2部分重叠-len2长
        else if(len1MinX < len2MinX && len1MaxX > len2MinX  && len1MaxX < len2MaxX)
            return Partial_1;
        // 检查是否len1、len2部分重叠-len1长
        else if(len2MinX < len1MinX && len2MaxX > len1MinX && len2MaxX < len1MaxX)
            return Partial_2;
        // 如果以上条件均不满足，则不重叠
        else
            return None;
    }
    else
    {
        //y方向平行 获取len1/len2最大/最小y值 使用qRound实现四舍五入
        double len1MinY = std::min(len1.a1.ay+maxvalue, len1.a2.ay+maxvalue);
        double len1MaxY = std::max(len1.a1.ay+maxvalue, len1.a2.ay+maxvalue);
        double len2MinY = std::min(len2.a1.ay+maxvalue, len2.a2.ay+maxvalue);
        double len2MaxY = std::max(len2.a1.ay+maxvalue, len2.a2.ay+maxvalue);

        // 检查是否完全重叠
        if(std::abs(len1MinY-len2MinY)<ZERO && std::abs(len1MaxY-len2MaxY)<ZERO)
            return Full;
        // 检查是否len1包含len2
        else if(len1MinY <= len2MinY  && len1MaxY >= len2MaxY && ((len1MaxY!=len2MaxY)||(len1MinY!=len2MinY)))
            return Contains_1;
        // 检查是否len2包含len1
        else if(len2MinY <= len1MinY && len2MaxY >= len1MaxY && ((len1MaxY!=len2MaxY)||(len1MinY!=len2MinY)))
            return Contains_2;
        // 检查是否len1、len2部分重叠-len2高
        else if(len1MinY < len2MinY && len1MaxY > len2MinY && len1MaxY < len2MaxY)
            return Partial_1;
        // 检查是否len1、len2部分重叠-len1高
        else if(len2MinY < len1MinY && len2MaxY > len1MinY && len2MaxY < len1MaxY)
            return Partial_2;
        // 如果以上条件均不满足，则不重叠
        else
            return None;
    }
}
//替换平行重叠线段为偏移线段
void EmbData::setCut2RemoveOverLapLines()
{
    qDebug()<<__FUNCTION__;

    bool delOverlapLines = g_pSettings->readFromIniFile("FlatPanelAlgorithm/AreParallel").toBool();
    if(!delOverlapLines)
    {
        return;
    }

    const char* dataPtr = m_embAbsData.constData();
    DataDs16FileHead head;
    memcpy(&head, dataPtr, sizeof(DataDs16FileHead));
    int maxvalue = head.maxX > head.maxY ? head.maxX:head.maxY;
    dataPtr += sizeof(DataDs16FileHead);//偏移指针到数据点位置

    //将 m_embAbsData 中的所有 DsAbsItem 放入 items 集合中
    QVector<DsAbsItem> items;
    int itemCount = head.itemNums;
    items.resize(itemCount);
    for (int i = 0; i < itemCount; ++i)
    {
        memcpy(&items[i], dataPtr, sizeof(DsAbsItem));
        dataPtr += sizeof(DsAbsItem);
    }

    QMap<u8, QVector<LineSegment>> segmentsByCtrl;//划分出ctrl为圆刀和振刀的数据点
    for (int i = 0; i < items.size() - 1; ++i)
    {
        DsAbsItem a1 = items[i];
        DsAbsItem a2 = items[i + 1];
        if (a2.ctrl != DATA_RKNIFE && a2.ctrl != DATA_SKNIFE) continue;
        segmentsByCtrl[a2.ctrl].append({i, i+1, a1, a2, a2.ctrl});
    }

    QVector<DsAbsItem> newItems = items;//新版数据点的集合
    QVector<int> modifyIndices;//要修改ctrl点的下标索引集合
    QVector<u8> newCtrls;//要修改的ctrl集合

    QVector<int> insertIndex;//要额外插入点的索引集合
    QVector<DsAbsItem> insertItems;//要额外插入点的集合
    insertIndex.clear();
    insertItems.clear();

    // 遍历每个ctrl组
    for (auto ctrlIter = segmentsByCtrl.begin(); ctrlIter != segmentsByCtrl.end(); ++ctrlIter)
    {
        auto& segments = ctrlIter.value();
        for (int i = 0; i < segments.size(); ++i)
        {
            LineSegment& len1 = segments[i];
            bool len1Horizontal = isHorizontal(len1);
#if(0)
            qDebug()<<"len1 a1 ctrl:"<<len1.a1.ctrl
                   <<"len1 a1 ax:"<<len1.a1.ax
                  <<"len1 a1 ay:"<<len1.a1.ay
                 <<"len1 a2 ctrl:"<<len1.a2.ctrl
                <<"len1 a2 ax:"<<len1.a2.ax
               <<"len1 a2 ay:"<<len1.a2.ay;
#endif
            for (int j = i + 1; j < segments.size(); ++j)
            {
                LineSegment& len2 = segments[j];
                OverlapType overlap = checkOverlap(len1, len2,maxvalue);
                if (overlap == None)
                    continue;

                // 获取线段方向
                bool isLen1Asc = isAscending(len1, len1Horizontal);

                // 处理完全重叠
                if (overlap == Full)
                {
                    // 修改len1的ctrl为2（根据需求调整）
                    modifyIndices.append(len1.indexA2);
                    newCtrls.append(DATA_OFFSET);
                }
                //len1、len2部分重叠--len2高/宽
                else if(overlap == Partial_1)
                {
                    if(len1Horizontal)//水平--x方向平行-len2宽
                    {
                        double len2MinX = std::min(len2.a1.ax, len2.a2.ax);
                        if(isLen1Asc)// a1自左到右
                        {
                            //在a1点后插入（c1,c2)中有较小x值的点，并且该点的ctrl与a1点ctrl相同
                            DsAbsItem tp = len1.a2;
                            tp.ar = len1.a1.ar;
                            tp.ax = len2MinX;
                            insertIndex.append(len1.indexA1);
                            insertItems.append(tp);

                            //修改a2点ctrl为2
                            modifyIndices.append(len1.indexA2);
                            newCtrls.append(DATA_OFFSET);
                        }
                        else
                        {//a1自右到左
                            //在a1点后插入（c1,c2)中有较小x值的点，并且修改该点的ctrl为2
                            DsAbsItem tp = len1.a2;
                            tp.ar = len1.a1.ar;
                            tp.ax = len2MinX;
                            tp.ctrl = DATA_OFFSET;
                            insertIndex.append(len1.indexA1);
                            insertItems.append(tp);
                        }
                    }
                    else//垂直--y方向平行-len2高
                    {
                        double len2MixY = std::min(len2.a1.ay, len2.a2.ay);
                        if(isLen1Asc)// a1自下到上
                        {
                            //在a1点后插入（c1,c2)中有较小y值的点
                            DsAbsItem tp = len1.a2;
                            tp.ar = len1.a1.ar;
                            tp.ay = len2MixY;
                            insertIndex.append(len1.indexA1);
                            insertItems.append(tp);

                            //修改a2点ctrl为2
                            modifyIndices.append(len1.indexA2);
                            newCtrls.append(DATA_OFFSET);
                        }
                        else//a1自上到下
                        {
                            //在a1点后插入（c1,c2)中有较小y值的点，并且修改该点的ctrl为2
                            DsAbsItem tp = len1.a2;
                            tp.ar = len1.a1.ar;
                            tp.ay = len2MixY;
                            tp.ctrl = DATA_OFFSET;
                            insertIndex.append(len1.indexA1);
                            insertItems.append(tp);
                        }
                    }
                }
                //len1、len2部分重叠--len1高/宽
                else if(overlap == Partial_2)
                {
                    if(len1Horizontal)//水平 x方向
                    {
                        double len2MaxX = std::max(len2.a1.ax, len2.a2.ax);
                        if(isLen1Asc)// a1自左到右
                        {
                            //在a1点后插入（c1,c2)中有较大x值的点，并且修改该点的ctrl为2
                            DsAbsItem tp = len1.a2;
                            tp.ar = len1.a1.ar;
                            tp.ax = len2MaxX;
                            tp.ctrl = DATA_OFFSET;
                            insertIndex.append(len1.indexA1);
                            insertItems.append(tp);
                        }else//a1自右到左
                        {
                            //在a1点后插入（c1,c2)中有较大x值的点并且修改该点的ctrl为与a1点ctrl相同
                            DsAbsItem tp = len1.a2;
                            tp.ar = len1.a1.ar;
                            tp.ax = len2MaxX;
                            insertIndex.append(len1.indexA1);
                            insertItems.append(tp);

                            //修改a2点ctrl为2
                            modifyIndices.append(len1.indexA2);
                            newCtrls.append(DATA_OFFSET);
                        }
                    }
                    else//垂直 y方向
                    {
                        double len2MaxY = std::max(len2.a1.ay, len2.a2.ay);
                        if(isLen1Asc)// a1自下到上
                        {
                            //在a1点后插入（c1,c2)中有较小y值的点并且修改该点的ctrl为与a1点ctrl相同
                            DsAbsItem tp = len1.a2;
                            tp.ar = len1.a1.ar;
                            tp.ay = len2MaxY;
                            tp.ctrl = DATA_OFFSET;
                            insertIndex.append(len1.indexA1);
                            insertItems.append(tp);
                        }else//a1自上到下
                        {
                            //在a1点后插入（c1,c2)中有较小y值的点
                            DsAbsItem tp = len1.a2;
                            tp.ar = len1.a1.ar;
                            tp.ay = len2MaxY;
                            insertIndex.append(len1.indexA1);
                            insertItems.append(tp);

                            //修改a2点ctrl为2
                            modifyIndices.append(len1.indexA2);
                            newCtrls.append(DATA_OFFSET);
                        }
                    }
                }
                //包含-len1包含len2
                else if(overlap == Contains_1)
                {
                    if(len1Horizontal)//水平 x方向
                    {
                        double len2MinX = std::min(len2.a1.ax, len2.a2.ax);
                        double len2MaxX = std::max(len2.a1.ax, len2.a2.ax);
                        if(isLen1Asc)// a1自左到右
                        {
                            //先插入len2的(a1,a2)的x值最小的点，ctrl与len1-a1相同
                            DsAbsItem tp = len1.a2;
                            tp.ar = len1.a1.ar;
                            tp.ax = len2MinX;
                            insertIndex.append(len1.indexA1);
                            insertItems.append(tp);
                            //再插入len2的(a1,a2)的x值最大的点，修改ctrl为偏移（2）
                            tp.ax = len2MaxX;
                            tp.ctrl = DATA_OFFSET;
                            insertIndex.append(len1.indexA1);
                            insertItems.append(tp);
                        }else// a1自右到左
                        {
                            //先插入len2的(a1,a2)的x值最大的点，ctrl与len1-a1相同
                            DsAbsItem tp = len1.a2;
                            tp.ar = len1.a1.ar;
                            tp.ax = len2MaxX;
                            insertIndex.append(len1.indexA1);
                            insertItems.append(tp);
                            //再插入len2的(a1,a2)的x值最小的点，修改ctrl为偏移（2）
                            insertIndex.append(len1.indexA1);
                            tp.ax = len2MinX;
                            tp.ctrl = DATA_OFFSET;
                            insertItems.append(tp);
                        }
                    }
                    else//垂直 y方向
                    {
                        double len2MinY = std::min(len2.a1.ay, len2.a2.ay);
                        double len2MaxY = std::max(len2.a1.ay, len2.a2.ay);
                        if(isLen1Asc)// a1自下到上
                        {
                            //先插入len2的(a1,a2)的y值最小的点，ctrl与len1-a1相同
                            DsAbsItem tp = len1.a2;
                            tp.ar = len1.a1.ar;
                            tp.ay = len2MinY;
                            insertIndex.append(len1.indexA1);
                            insertItems.append(tp);
                            //再插入len2的(a1,a2)的y值最大的点，修改ctrl为偏移（2）
                            tp.ay = len2MaxY;
                            tp.ctrl = DATA_OFFSET;
                            insertIndex.append(len1.indexA1);
                            insertItems.append(tp);
                        }else// a1自上到下
                        {
                            //先插入len2的(a1,a2)的y值最大的点，ctrl与len1-a1相同
                            DsAbsItem tp = len1.a2;
                            tp.ar = len1.a1.ar;
                            tp.ay = len2MaxY;
                            insertIndex.append(len1.indexA1);
                            insertItems.append(tp);
                            //再插入len2的(a1,a2)的y值最小的点，修改ctrl为偏移（2）
                            tp.ay = len2MinY;
                            tp.ctrl = DATA_OFFSET;
                            insertIndex.append(len1.indexA1);
                            insertItems.append(tp);
                        }
                    }
                }
                //包含-len2包含len1
                else if(overlap == Contains_2)
                {
                    //修改len1的a2点为偏移（2）
                    modifyIndices.append(len1.indexA2);
                    newCtrls.append(DATA_OFFSET);
                }
            }
        }
    }

    // 应用修改
    for (int i = 0; i < modifyIndices.size(); ++i)
    {
        if (modifyIndices[i] < newItems.size())
        {
            newItems[modifyIndices[i]].ctrl = newCtrls[i];
        }
    }

    //排序新增数据点
    for(int i = 0;i<insertIndex.size();i++)
    {
        for(int j = i;j<insertIndex.size();j++)
        {
            if( (insertIndex[i]==insertIndex[j]) && (insertItems[i].ctrl==insertItems[j].ctrl) )
            {
                double tp_x,tp_y=0;
                if(std::abs(insertItems[i].ax-insertItems[j].ax)<=100)
                {
                    if(insertItems[i].ay>insertItems[j].ay)
                    {
                        tp_y = insertItems[i].ay;
                        insertItems[i].ay = insertItems[j].ay;
                        insertItems[j].ay = tp_y;
                    }
                }
                else if(std::abs(insertItems[i].ay-insertItems[j].ay)<=100)
                {
                    if(insertItems[i].ax>insertItems[j].ax)
                    {
                        tp_x = insertItems[i].ax;
                        insertItems[i].ax = insertItems[j].ax;
                        insertItems[j].ax = tp_x;
                    }
                }
            }

            if(insertIndex[i]==insertIndex[j] &&
                    insertItems[i].ax==insertItems[j].ax &&
                    insertItems[i].ay==insertItems[j].ay &&
                    insertItems[i].ctrl!=insertItems[j].ctrl)
            {
                if(insertItems[i].ctrl != DATA_OFFSET)
                {
                    insertItems[j].ctrl = insertItems[i].ctrl;
                    insertItems[i].ctrl = DATA_OFFSET;
                }
            }
        }
    }

    //插入新增数据点
    int removeindex = 1;
    if(insertIndex.size()!=0)
    {
        for(int j=0;j<insertIndex.size();j++)
        {
            newItems.insert(insertIndex[j]+removeindex,insertItems[j]);
            removeindex++;
        }
    }

    // 更新数据
    QByteArray newData;
    newData.append((const char*)&head, sizeof(DataDs16FileHead));
    for (const DsAbsItem& item : newItems)
    {
        newData.append((const char*)&item, sizeof(DsAbsItem));
    }
    m_embAbsData.clear();
    m_embAbsData = newData;

    // 更新头信息
    DataDs16FileHead* newHead = (DataDs16FileHead*)m_embAbsData.data();
    newHead->itemNums = newItems.size();
    newHead->dataSize = newItems.size()*sizeof(DsAbsItem);

    m_editedflag = 1;

    setCut2RemoveErroData2();       // 去除异常节点数据 bingo 此函数主要目的是将2(12,12)-35(12,12)-35(x,y)变为2(12,12)-35(x,y)
    setCut2recalculateAngles2();    // 重新计算角度

    return;
}

// 计算最大行进速度 (返回值单位: 0.01mm/s)
// 输入
//#define     CUT_OFFSET_SPD        (100)                 // 偏移速度 ,单位0.01mm/s
//#define     CUT_DRAWING_SPD       (100)                 // 画笔速度 ,单位mm/s
//#define     CUT_CUTTING_SPD       (100)                 // 切割速度 ,单位mm/s
//#define     CUT_LEFT_TIME         (1)                   // 升降机头时间 ,单位s
//#define     CUT_SPD_ADJ           (100)                 // 行进速度校准 ,范围50%~200% 单位%
int EmbData:: setCut2CalMaxSpd()
{
    int cutXWindow = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutXLengh").toInt();
    if(cutXWindow == 0)
    {
        cutXWindow = 500000;
    }

    int j;
    int size = m_embDs16Data.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(Ds16Item);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }
    else
    {
        qDebug()<<"stepsize"<<stepsize;
    }

    Ds16Item * pData = (Ds16Item *)(m_embDs16Data.data() + sizeof(DataDs16FileHead));
    Ds16Item * embDataPtr = pData;
    Ds16Item * curDataPtr;

    // 数据区
    {
        int winNum;
        winNum = 0;         // 窗口个数范围
        u16 curWin;         // 当前窗口

        curDataPtr = embDataPtr;
        for (j = 0; j < stepsize; j++)
        {
            curWin = MAKEWORD(curDataPtr->action[0],curDataPtr->action[1]);
            if (winNum < curWin)
            {
                winNum = curWin;
            }
            curDataPtr++;
        }
        winNum++;

        double winSpd[winNum];      // 窗口速度
        double penlen[winNum];      // 画笔长度
        double cutlen[winNum];      // 裁切长度
        double ofstlen[winNum];     // 偏移长度
        u32 leftTim[winNum];        // 升降次数

        for (j = 0; j < winNum; j++)
        {
            winSpd[j] = 0;         // 窗口速度
            penlen[j] = 0;         // 画笔长度
            cutlen[j] = 0;         // 裁切长度
            ofstlen[j] = 0;        // 偏移长度
            leftTim[j] = 0;        // 升降次数
        }

        // 数据区
        {
            double lastX = 0;
            double lastY = 0;
            double curX = 0;
            double curY = 0;
            double len = 0;
            u8 laetCtrl = DATA_OFFSET;

            curDataPtr = embDataPtr;
            for (j = 0; j < stepsize; j++)
            {
                if (j == 0)
                {
                }
                else if (curDataPtr->ctrl == DATA_OFFSET)
                {// 偏移数据
                    curX = curDataPtr->dx;
                    curY = curDataPtr->dy;
                    len = sqrt((lastX-curX)*(lastX-curX)+(lastY-curY)*(lastY-curY));
                    curWin = MAKEWORD(curDataPtr->action[0],curDataPtr->action[1]);
                    ofstlen[curWin] += len;
                }
                else if (curDataPtr->ctrl == DATA_DRAWING)
                {// 画笔数据
                    curX = curDataPtr->dx;
                    curY = curDataPtr->dy;
                    len = sqrt((lastX-curX)*(lastX-curX)+(lastY-curY)*(lastY-curY));
                    curWin = MAKEWORD(curDataPtr->action[0],curDataPtr->action[1]);
                    penlen[curWin] += len;
                }
                else
                {// 裁切数据
                    curX = curDataPtr->dx;
                    curY = curDataPtr->dy;
                    len = sqrt((lastX-curX)*(lastX-curX)+(lastY-curY)*(lastY-curY));
                    cutlen[curDataPtr->action[0]] += len;
                }

                if (laetCtrl != curDataPtr->ctrl)
                {
                    laetCtrl = curDataPtr->ctrl;
                    curWin = MAKEWORD(curDataPtr->action[0],curDataPtr->action[1]);
                    leftTim[curWin] += 2;       // 升降次数+2
                }

                lastX = curDataPtr->dx;
                lastY = curDataPtr->dy;
                curDataPtr++;
            }

            for (j = 0; j < winNum; j++)
            {// 计算过窗传送电机最大行进速度
                double time = 0;

                time += cutlen[j] / CUT_CUTTING_SPD;    // 裁切时间(单位:s)
                time += penlen[j] / CUT_DRAWING_SPD;    // 画笔时间(单位:s)
                time += ofstlen[j] / CUT_OFFSET_SPD;    // 偏移时间(单位:s)
                time += leftTim[j] * CUT_LEFT_TIME;     // 升降时间(单位:s)

                if (time == 0)
                {
                    winSpd[j] = CUT_SPD_MAX;
                }
                else
                {
                    winSpd[j] = ((cutXWindow*3/10) * CUT_SPD_ADJ / 100 / time);
                }

                if (winSpd[j] > CUT_SPD_MAX)
                {
                    winSpd[j] = CUT_SPD_MAX;
                }

                if (winSpd[j] == 0)
                {
                    winSpd[j] = 1;
                }
                qDebug()<<"winSpd["<<j<<"]="<<winSpd[j];
            }

            {// 将最大速度保存到针步中
                U32ToU8 curmaxpps;
                for (j = 0; j < stepsize; j++)
                {
                    curWin = MAKEWORD(embDataPtr->action[0],curDataPtr->action[1]);
                    curmaxpps.buf32 = (u32)(winSpd[curWin]);
                    memcpy(&embDataPtr->rev,&curmaxpps.buf32,4);
                    embDataPtr++;
                }
            }
        }

    }
    return 0;
}

// 重新计算角度
void EmbData::recalculateAngles()
{
    qDebug()<<__FUNCTION__;
    u32 size = m_embAbsData.size();
    if (size < sizeof(DataDs16FileHead))
    {
        return ;
    }

    DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead));
    //DsAbsItem * absDataPtr = pData;  //中间数据针步
    int stepsize = (size - sizeof(DataDs16FileHead))/sizeof(DsAbsItem);

    DsAbsItem lastItem = {}; // 默认初始化清零
    qDebug() << __FUNCTION__ << "stepsize:" << stepsize;

    for (int j = 0; j < stepsize-1; ++j)
    {
        DsAbsItem* current = &pData[j];
        s32 ar = calculateAngles(current->ax, current->ay, lastItem.ax, lastItem.ay);
        current->ar = ar;
        lastItem = *current; // 更新lastItem为当前值
    }
}

s32 EmbData::calculateAngles(double endX, double endY, double beginX, double beginY)
{
    double Dx = endX - beginX ;
    double Dy = endY - beginY ;

    double tar = atan2(Dy,Dx);
    s32 ar = (tar * 10000+0.5*(tar>0?1:-1));
    return ar;
}

//切割数据结尾的补偿  移动结尾切割点的方法
void EmbData::cutDataEndCompensate(DsAbsItem &curItem,DsAbsItem &preItem, double comDistance)
{
    if(comDistance <= 0.0)
        return;

    double preR = curItem.ar / 10000.0;
    double comDisX = qCos(preR) * comDistance;
    double comDisY = qSin(preR) * comDistance;
    //切割数据正向移动
    curItem.ax += comDisX;
    curItem.ay += comDisY;

    if(preItem.ctrl == 0){}//为了去掉警告
}

//切割数据结尾的补偿  移动结尾切割点的方法
void EmbData::cutDataEndCompensate2(DsAbsItem &curItem,DsAbsItem &preItem, double comDistance, double maxY, double minY)
{
    if(comDistance <= 0.0)
        return;

    double preR = curItem.ar / 10000.0;
    double comDisX = qCos(preR) * comDistance;
    double comDisY = qSin(preR) * comDistance;
    //切割数据正向移动
    curItem.ax += comDisX;
    curItem.ay += comDisY;

    if(curItem.ay>maxY)
    {
        curItem.ay = maxY;
    }
    if(curItem.ay<minY)
    {
        curItem.ay = minY;
    }

    if(preItem.ctrl == 0){}//为了去掉警告
}

//添加切割数据结尾 垂直补偿 向内补偿
void EmbData::cutDataVertCut(DsAbsItem &curItem, double comDistance, QByteArray &cutAbsData,int &newstepnum)
{
    if(comDistance <= 0.0)
        return;

    //添加原始切割终点
    newstepnum++;
    cutAbsData.append((char*)(&curItem), sizeof(DsAbsItem));
    qDebug()<<"CrossCut ADD Point:" <<"  x:"<<curItem.ax <<"  y:"<<curItem.ay<< "ar:" << curItem.ar <<"  ctrl:"<< QString::number(curItem.ctrl,16);

    int angle = 45;//45度夹角
    double includedAngle = (angle * PI / 180) * 10000; //转换为弧度

    //新增偏移点  移动到小横切起始点
    double arOffsetPoint = curItem.ar +includedAngle ;
    double offsetX = qCos(arOffsetPoint / 10000.0) * comDistance;
    double offsetY = qSin(arOffsetPoint / 10000.0) * comDistance;
    DsAbsItem offsetPoint;
    memcpy((char*)&offsetPoint, (char*)&curItem, sizeof(DsAbsItem));
    offsetPoint.ctrl = DATA_OFFSET;
    offsetPoint.ax -= offsetX;
    offsetPoint.ay -= offsetY;
    offsetPoint.ar = calculateAngles(offsetPoint.ax,offsetPoint.ay,curItem.ax,curItem.ay);
    newstepnum++;
    cutAbsData.append((char*)(&offsetPoint), sizeof(DsAbsItem));
    qDebug()<<"CrossCut ADD offsetPoint:" <<"  x:"<<offsetPoint.ax <<"  y:"<<offsetPoint.ay<< "ar:" << offsetPoint.ar <<"  ctrl:"<< QString::number(offsetPoint.ctrl,16);;

    //小横切针步
    //此针会在调用函数的循环中被添加
    double arCutPoint = curItem.ar - includedAngle;
    offsetX = qCos(arCutPoint / 10000.0) * comDistance;
    offsetY = qSin(arCutPoint / 10000.0) * comDistance;
    curItem.ax -= offsetX;
    curItem.ay -= offsetY;
    curItem.ar = calculateAngles(curItem.ax,curItem.ay,offsetPoint.ax,offsetPoint.ay);
    qDebug()<<"cur Point:" <<"  x:"<<curItem.ax <<"  y:"<<curItem.ay<< "ar:" << curItem.ar <<"  ctrl:"<< QString::number(curItem.ctrl,16);;

}

//切割数据开头的补偿  移动切割起始点
void EmbData::cutDataStartCompensate(DsAbsItem &curItem, DsAbsItem &preItem, DsAbsItem &nextItem, double comDistance)
{
    if(comDistance <= 0.0)
        return;

    double nextR = nextItem.ar / 10000.0; //下一针的绝对角度
    double comDisX = qCos(nextR) * comDistance;
    double comDisY = qSin(nextR) * comDistance;
    //跨步数据反向移动
    curItem.ax -= comDisX;
    curItem.ay -= comDisY;
    //计算偏移角度
    curItem.ar = calculateAngles(curItem.ax, curItem.ay, preItem.ax, preItem.ay);

    if(preItem.ax==0){};//去除编译警告
}

//切割数据开头的补偿  移动切割起始点
void EmbData::cutDataStartCompensate2(DsAbsItem &curItem, DsAbsItem &preItem, DsAbsItem &nextItem, double comDistance, double maxY,double minY)
{
    if(comDistance <= 0.0)
        return;

    double nextR = nextItem.ar / 10000.0; //下一针的绝对角度
    double comDisX = qCos(nextR) * comDistance;
    double comDisY = qSin(nextR) * comDistance;
    //跨步数据反向移动
    curItem.ax -= comDisX;
    curItem.ay -= comDisY;

    if(curItem.ay<minY)
    {
        curItem.ay = minY;
    }
    if(curItem.ay>maxY)
    {
        curItem.ay = maxY;
    }

    //计算偏移角度
    curItem.ar = calculateAngles(curItem.ax, curItem.ay, preItem.ax, preItem.ay);

    if(preItem.ax==0){};//去除编译警告
}

bool EmbData::isCutCtrl(u8 &ctrl)
{
    return (ctrl == DATA_RKNIFE || ctrl == DATA_SKNIFE );
}

// 在空白窗口增加画笔数据
void EmbData::addPenData(QVector<QVector<QByteArray>> &pVisited,
                         QVector<QVector<QByteArray>> &rVisited,
                         QVector<QVector<QByteArray>> &sVisited,
                         int winNum,double xWin,double xminPos,double yminPos)
{
    if (0)
    {
        qDebug()<<"winNum:"<<winNum
               <<",xWin:"<<xWin
              <<",xminPos:"<<xminPos
             <<",yminPos:"<<yminPos
               ;
    }

    DsAbsItem * tmpDataPtr;  //数据针步

    int cont = 0;           // 拐点个数
    int size = 0;           // 数据个数
    double ax,ay;

    for (int i=0;i<winNum;i++)
    {
        ax = 0;
        ay = 0;
        cont = 0;
        if (pVisited[i].size() == 0)
        {// 如果当前窗口里三种数据都是空的,则需要插入一个数据
            if ( (rVisited[i].size() == 0) &&
                 (sVisited[i].size() == 0) &&
                 1 )
            {// 当前窗口全空
                ax = xminPos + xWin * i + 1000;
                ay = yminPos + 1000;
            }
            else if ((rVisited[i].size() != 0) &&
                     (sVisited[i].size() == 0) &&
                     1 )
            {// 只有圆刀有数据
                size = rVisited[i].size();

                for (int j = 0; j<size; j++)
                {
                    tmpDataPtr = (DsAbsItem *)(rVisited[i][j].data());
                    if (tmpDataPtr->ctrl == DATA_ANGLE_OLD)
                    {
                        cont++;
                    }
                    else if ((ax == 0) && (ay == 0))
                    {
                        ax = tmpDataPtr->ax;
                        ay = tmpDataPtr->ay;
                    }
                }
            }
            else if ((rVisited[i].size() == 0) &&
                     (sVisited[i].size() != 0) &&
                     1 )
            {// 只有震刀有数据
                size = sVisited[i].size();

                for (int j = 0; j<size; j++)
                {
                    tmpDataPtr = (DsAbsItem *)(sVisited[i][j].data());
                    if (tmpDataPtr->ctrl == DATA_ANGLE_OLD)
                    {
                        cont++;
                    }
                    else if ((ax == 0) && (ay == 0))
                    {
                        ax = tmpDataPtr->ax;
                        ay = tmpDataPtr->ay;
                    }
                }
            }

            if ((cont < 2) &&
                    ((ax != 0) || (ay != 0)) &&
                    1)
            { // 在ax,ay的位置插入一个画笔数据
                DsAbsItem absItem;
                QByteArray ary;

                absItem.ctrl = DATA_ANGLE_OLD;
                absItem.action = i;
                absItem.ar = 15707.5;
                absItem.ax = ax;
                absItem.ay = ay;

                ary.clear();
                ary.append((char*)&absItem, sizeof(DsAbsItem)); // 增加拐点数据
                pVisited[i].append(ary);

                absItem.ctrl = DATA_DRAWING;
                ary.clear();
                ary.append((char*)&absItem, sizeof(DsAbsItem)); // 增加画笔起点数据
                pVisited[i].append(ary);

                absItem.ay += 100;
                ary.clear();
                ary.append((char*)&absItem, sizeof(DsAbsItem)); // 增加画笔终点数据
                pVisited[i].append(ary);

            }
        }
        else  //if (pVisited[i].size() != 0)
        {
            if ( (rVisited[i].size() == 0) &&
                 (sVisited[i].size() == 0) &&
                 1 )
            {// 当前窗口全空
                size = pVisited[i].size();

                for (int j = 0; j<size; j++)
                {
                    tmpDataPtr = (DsAbsItem *)(pVisited[i][j].data());
                    if (tmpDataPtr->ctrl == DATA_ANGLE_OLD)
                    {
                        cont++;
                    }
                    else if ((ax == 0) && (ay == 0))
                    {
                        ax = tmpDataPtr->ax;
                        ay = tmpDataPtr->ay;
                    }
                }
            }

            if ((cont < 2) &&
                    ((ax != 0) || (ay != 0)) &&
                    1)
            { // 在ax,ay的位置插入一个画笔数据
                DsAbsItem absItem;
                QByteArray ary;

                absItem.ctrl = DATA_ANGLE_OLD;
                absItem.action = i;
                absItem.ar = 15707.5;
                absItem.ax = ax;
                absItem.ay = ay;

                ary.clear();
                ary.append((char*)&absItem, sizeof(DsAbsItem)); // 增加拐点数据
                pVisited[i].insert(0,ary);

                absItem.ctrl = DATA_DRAWING;
                ary.clear();
                ary.append((char*)&absItem, sizeof(DsAbsItem)); // 增加画笔起点数据
                pVisited[i].insert(1,ary);

                absItem.ay += 100;
                ary.clear();
                ary.append((char*)&absItem, sizeof(DsAbsItem)); // 增加画笔终点数据
                pVisited[i].insert(2,ary);

            }
        }
    }   // for (int i=0;i<winNum;i++)
}

// 梳理数据
void EmbData::optimizationOrder(QVector<QVector<QByteArray>>&visited,int winNum)
{
    double lastX,lastY,curX,curY,len,minlen;
    int stepnum = 0;
    DsAbsItem * tmpDataPtr;  //数据针步

    lastX = S32_MAX;
    lastY = S32_MAX;

    for (int i=0;i<winNum;i++)
    {// 求起始点坐标最小值
        stepnum = visited[i].size();   // 求当前数据每个窗口中有多少点

        for (int j = 0;j<stepnum;j++)
        {// 判断段数
            tmpDataPtr = (DsAbsItem *)(visited[i][j].data());
            if (0)
            {
                qDebug() <<"i:"<<i<<"j:"<<j
                       <<"ctrl:"<<tmpDataPtr->ctrl<<"action:"<<tmpDataPtr->action
                      <<"ax:"<<tmpDataPtr->ax<<"ay:"<<tmpDataPtr->ay<<"ar:"<<tmpDataPtr->ar;
            }

            if (lastX > tmpDataPtr->ax)
            {
                lastX = tmpDataPtr->ax;
            }
            if (lastY > tmpDataPtr->ay)
            {
                lastY = tmpDataPtr->ay;
            }
        }
    }

    //qDebug() <<"begX:"<<lastX/100 <<",begY:"<<lastY/100;

    for (int i=0;i<winNum;i++)
    {
        int duan = 0;       // 数据段
        stepnum = visited[i].size();   // 数据
        //        qDebug()<<" ";
        //        qDebug()<<" ";
        //        qDebug()<<" ";
        //        qDebug()<<"winNum:"<<i;

        for (int j = 0;j<stepnum;j++)
        {// 判断段数
            tmpDataPtr = (DsAbsItem *)(visited[i][j].data());
            if (tmpDataPtr->ctrl == DATA_ANGLE_OLD)
            {
                duan++;
            }
            else
            {
                continue;
            }
        }
        if (duan == 0)
        {
            continue;
        }

        QVector<QVector<QByteArray>> duanData(duan, QVector<QByteArray>(0));      // 临时数据 (正向)

        int k = -1;
        for (int j = 0;j<stepnum;j++)
        {// 拆分段,给临时数据赋值
            tmpDataPtr = (DsAbsItem *)(visited[i][j].data());
            if (tmpDataPtr->ctrl == DATA_ANGLE_OLD)
            {
                k++;
            }
            else if (k>=0)
            {
                duanData[k].append(QByteArray((char*)tmpDataPtr, sizeof(DsAbsItem)));     // 保存正向数据
            }
        }

        if (0)
        {// 打印每个段的端点数据
            for (k=0;k<duan;k++)
            {
                DsAbsItem * tmpDataPtrBeg;  //数据针步
                DsAbsItem * tmpDataPtrEnd;  //数据针步
                tmpDataPtrBeg = (DsAbsItem *)(duanData[k][0].data());
                tmpDataPtrEnd = (DsAbsItem *)(duanData[k][duanData[k].size()-1].data());

                qDebug()<<"duan:"<<k
                       <<",bx:"<<tmpDataPtrBeg->ax/100 <<",by:"<<tmpDataPtrBeg->ay/100
                      <<",ex:"<<tmpDataPtrEnd->ax/100 <<",ey:"<<tmpDataPtrEnd->ay/100
                        ;
            }
            qDebug()<<" ";
        }

        if(1)
        {// 重组数据
            int nearDuan;       // 最近的段
            visited[i].clear();

            for (int j=0;j<duan;j++)
            {// 正反方向,判断最近的点
                minlen = std::numeric_limits<double>::max();
                nearDuan = 0;       // 最近的段

                for (k=(duan-1);k>=0;k--)
                {// 正反方向,判断最近的点
                    if (duanData[k].size() != 0) // 未判断过的段
                    {
                        // 终点点距离
                        tmpDataPtr = (DsAbsItem *)(duanData[k][duanData[k].size()-1].data());
                        curX = tmpDataPtr->ax;
                        curY = tmpDataPtr->ay;
                        len = sqrt((lastX-curX)*(lastX-curX)+(lastY-curY)*(lastY-curY));
                        if (minlen >= len)
                        {
                            minlen = len;
                            nearDuan = (k+1)*(-1);       // 最近的段
                        }

                        tmpDataPtr = (DsAbsItem *)(duanData[k][0].data());
                        // 起点距离
                        curX = tmpDataPtr->ax;
                        curY = tmpDataPtr->ay;
                        len = sqrt((lastX-curX)*(lastX-curX)+(lastY-curY)*(lastY-curY));
                        if (minlen >= len)
                        {
                            minlen = len;
                            nearDuan = (k+1);       // 最近的段
                        }

                    }
                }
                //qDebug()<<"duan:"<<j  <<",nearDuan:"<<nearDuan;

#if (0)     // 老程序(可以正常使用)
                if (nearDuan > 0)
                {// 正向赋值
                    nearDuan--;
                    int l = duanData[nearDuan].size();

                    tmpDataPtr = (DsAbsItem *)(duanData[nearDuan][0].data());
                    tmpDataPtr->ctrl = DATA_ANGLE_OLD;
                    visited[i].append(QByteArray((char*)tmpDataPtr, sizeof(DsAbsItem)));     // 增加拐点数据

                    for (k=0;k<l;k++)
                    {
                        tmpDataPtr = (DsAbsItem *)(duanData[nearDuan][k].data());
                        visited[i].append(QByteArray((char*)tmpDataPtr, sizeof(DsAbsItem)));     // 增加拐点数据
                    }

                    duanData[nearDuan].clear();
                }
                else
                {// 反向赋值
                    nearDuan = (nearDuan*(-1))-1;
                    //添加索引有效性检查
                    if (nearDuan < 0 || nearDuan >= duanData.size()) {
                        qDebug() << "Invalid nearDuan index:" << nearDuan;
                        continue;
                    }

                    int l = duanData[nearDuan].size();

                    tmpDataPtr = (DsAbsItem *)(duanData[nearDuan][l-1].data());
                    tmpDataPtr->ctrl = DATA_ANGLE_OLD;
                    if (tmpDataPtr->ar >= 0)
                    {
                        tmpDataPtr->ar -= PI10000;
                    }
                    else
                    {
                        tmpDataPtr->ar += PI10000;
                    }
                    visited[i].append(QByteArray((char*)tmpDataPtr, sizeof(DsAbsItem)));     // 增加拐点数据

                    for (k=0;k<l;k++)
                    {
                        tmpDataPtr = (DsAbsItem *)(duanData[nearDuan][l-1-k].data());
                        if (tmpDataPtr->ar >= 0)
                        {
                            tmpDataPtr->ar -= PI10000;
                        }
                        else
                        {
                            tmpDataPtr->ar += PI10000;
                        }

                        visited[i].append(QByteArray((char*)tmpDataPtr, sizeof(DsAbsItem)));     // 增加拐点数据
                    }

                    duanData[nearDuan].clear();
                }

#else
                DsAbsItem absItem;
                QByteArray ary;

                // 新程序,有问题,画笔过程中刀会转,而且降速不能用.
                if (nearDuan > 0)
                {// 正向赋值
                    nearDuan--;

                    int l = duanData[nearDuan].size();

                    memcpy(&absItem,duanData[nearDuan][0].data(),sizeof(DsAbsItem));
                    absItem.ctrl = DATA_ANGLE_OLD;
                    ary.clear();
                    ary.append((char*)&absItem, sizeof(DsAbsItem));
                    visited[i].append(ary);

                    for (k=0;k<l;k++)
                    {
                        tmpDataPtr = (DsAbsItem *)(duanData[nearDuan][k].data());
                        visited[i].append(QByteArray((char*)tmpDataPtr, sizeof(DsAbsItem)));     // 增加拐点数据
                    }

                    lastX = tmpDataPtr->ax;
                    lastY = tmpDataPtr->ay;
                    // qDebug()<<"nearDuan:"<<nearDuan<<"lastX:"<<lastX/100<<",lastY:"<<lastY/100;
                    duanData[nearDuan].clear();
                }
                else
                {// 反向赋值
                    nearDuan = (nearDuan*(-1))-1;
                    //添加索引有效性检查
                    if (nearDuan < 0 || nearDuan >= duanData.size()) {
                        qDebug() << "Invalid nearDuan index:" << nearDuan;
                        continue;
                    }

                    int l = duanData[nearDuan].size();

                    memcpy(&absItem,duanData[nearDuan][l-1].data(),sizeof(DsAbsItem));
                    absItem.ctrl = DATA_ANGLE_OLD;
                    if (absItem.ar >= 0)
                    {
                        absItem.ar -= PI10000;
                    }
                    else
                    {
                        absItem.ar += PI10000;
                    }
                    ary.clear();
                    ary.append((char*)&absItem, sizeof(DsAbsItem));
                    visited[i].append(ary);

                    for (k=0;k<l;k++)
                    {
                        tmpDataPtr = (DsAbsItem *)(duanData[nearDuan][l-1-k].data());
                        if (tmpDataPtr->ar >= 0)
                        {
                            tmpDataPtr->ar -= PI10000;
                        }
                        else
                        {
                            tmpDataPtr->ar += PI10000;
                        }
                        visited[i].append(QByteArray((char*)tmpDataPtr, sizeof(DsAbsItem)));     // 增加拐点数据
                    }

                    lastX = tmpDataPtr->ax;
                    lastY = tmpDataPtr->ay;
                    //qDebug()<<"nearDuan:"<<nearDuan<<"lastX:"<<lastX/100<<",lastY:"<<lastY/100;
                    duanData[nearDuan].clear();
                }
#endif
            }
        }

        if (0)
        {// 打印优化后的数据
            int k = -1;
            for (int j = 0;j<stepnum;j++)
            {// 拆分段,给临时数据赋值


                tmpDataPtr = (DsAbsItem *)(visited[i][j].data());
                if (tmpDataPtr->ctrl == DATA_ANGLE_OLD)
                {
                    k++;
                }
                else if (k>=0)
                {
                    duanData[k].append(QByteArray((char*)tmpDataPtr, sizeof(DsAbsItem)));     // 保存正向数据
                }
            }

            if (0)
            {// 打印每个段的端点数据
                for (k=0;k<duan;k++)
                {
                    DsAbsItem * tmpDataPtrBeg;  //数据针步
                    DsAbsItem * tmpDataPtrEnd;  //数据针步
                    tmpDataPtrBeg = (DsAbsItem *)(duanData[k][0].data());
                    tmpDataPtrEnd = (DsAbsItem *)(duanData[k][duanData[k].size()-1].data());

                    qDebug()<<"after duan:"<<k
                           <<",bx:"<<tmpDataPtrBeg->ax/100 <<",by:"<<tmpDataPtrBeg->ay/100
                          <<",ex:"<<tmpDataPtrEnd->ax/100 <<",ey:"<<tmpDataPtrEnd->ay/100
                            ;
                }
                qDebug()<<" ";
            }
        }
    }   // for (int i=0;i<winNum;i++)
}

// 主控参数(与主板参数同步更改)
//#define     CUT_SPD_MINPPS      (10)            // 最小切割速度, 范围 1--100，单位mm/s，默认 10
//#define     CUT_SPD_MAXPPS      (600)          // 最大切割速度, 范围 1--1200，单位mm/s，默认 1000
//#define     CUT_ADD_PPSG        (1000)           // 切割加速度, 范围 1--4000，单位mm/s2，默认 500
//#define     CUT_SLOW_ANGLE      (6000)          // 切割降速最小偏差角度，范围 0--18000，单位 0.01度，默认 3000
//#define     CUT_WORK_MINADD     (1)            // 工作最小加速度

#define     CUTTINGVX_MUTI      (5)             // 切割虚轴脉冲倍数
#define     PULSE_PER_MM        (100)           // 每毫米脉冲数
#define     RADIAN_ACCURACY		(10000)         // 万分之一弧度
#define     N1_FPGA_CLK         (72000000L)     // N1主板FPGA主频
#define     DEG_PER_CIRCLE		(360)           // 每圈的度数（单位 度）
#define     DEG001_PER_DEG		(100)
#define     DEG001_PER_CIRCLE	(DEG_PER_CIRCLE*DEG001_PER_DEG)     // 每圈的度数（单位 0.01度）

#define     MMPS_TO_PPS(mmps)           ((mmps)*PULSE_PER_MM)                       // 单位转换，由“毫米每秒”转换为“脉冲个数每秒”
#define     MMPSS_TO_PPSG(mmpss)        (N1_FPGA_CLK/(PULSE_PER_MM)/(mmpss))           // 单位转换，由“毫米每秒平方”转换为“脉冲个数每秒间隔”，间隔单位为1/72000000秒

#define     ROT_001DEG_TO_PITK(deg)     ((double)(deg)*2*PI*RADIAN_ACCURACY/DEG001_PER_CIRCLE)  // 单位转换，由“0.01度”转换为“万分之一弧度”
#define     VAxisMMPSToPPS(mmps)		(MMPS_TO_PPS(mmps) * CUTTINGVX_MUTI)		// 虚轴速度加快
#define     VAxisMMPSSToPPSG(mmpss)		(MMPSS_TO_PPSG(mmpss) / CUTTINGVX_MUTI)		// 加速度增大


//fillctrl.minchgpps = VAxisMMPSToPPS(g_pCuttingMcPara->workMinAdd*1.0);

u32 EmbData::CalcDisplacement(u32 pps1, u32 pps2, u32 calcTime)
{
    double temp;
    if (pps1 < pps2)
    {
        temp = (pps2-pps1);
    }
    else
    {
        temp = (pps1-pps2);
    }
    temp *= (pps1+pps2);
    temp *= calcTime;
    temp /= (2*N1_FPGA_CLK);
    return (u32)(temp+0.5);
}

s16 EmbData::Rot001ToPitk(s32 ang001)
{
    double temp = ang001;
    temp = ROT_001DEG_TO_PITK(temp);
    return (s16)temp;
}

// 计算切刀运动参数
// 输入:m_embDs16Data
// 输出:m_embDs16Data (在保留数据中增加最大速度)
int EmbData::setCutMoveParameters()
{
    int cutSpdMinpps = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutSpdMinpps").toInt();
    int cutSpdMaxpps = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutSpdMaxpps").toInt();
    int cutAddPpsg = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutAddPpsg").toInt();
    int cutSlowAngle = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutSlowAngle").toInt();
    int cutWorkMinadd = g_pSettings->readFromIniFile("FlatPanelAlgorithm/cutWorkMinadd").toInt();

    int size = m_embDs16Data.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("absdat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(Ds16Item);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }
    else
    {
        qDebug()<<"stepsize"<<stepsize;
    }

    Ds16Item * pData = (Ds16Item *)(m_embDs16Data.data() + sizeof(DataDs16FileHead));
    Ds16Item * embDataPtr = pData;
    Ds16Item * curDataPtr;

    // 数据区
    u32 minpps = VAxisMMPSToPPS(cutSpdMinpps);	// 最小速度
    u32 maxpps = VAxisMMPSToPPS(cutSpdMaxpps);	// 最大速度
    u32 addppsg = VAxisMMPSSToPPSG(cutAddPpsg);
    u32 minchgpps = VAxisMMPSToPPS(cutWorkMinadd);

    u32 decCount = CalcDisplacement(maxpps, 0, addppsg);	// 最大速度降速到0所需要的位移
    s16 slowAngle = Rot001ToPitk(cutSlowAngle);

    qDebug()<<"minpps"<<minpps;
    qDebug()<<"maxpps"<<maxpps;
    qDebug()<<"addppsg"<<addppsg;
    qDebug()<<"minchgpps"<<minchgpps;
    qDebug()<<"decCount"<<decCount;
    qDebug()<<"slowAngle"<<slowAngle;
    qDebug()<<"---------------------";

    U32ToU8 curmaxpps;
    u32 mintpps;       // 最小速度
    u32 temp;          // 临时速度

    int i,j;
    int geted = 0;
    s32 dx, dy, len, odx, ody, olen, mdx, mdy, mdxy;

    for (j = 0; j < stepsize; j++)
    {
        curmaxpps.buf32 = 0;
        mintpps = maxpps;       // 最小速度初值为最大切割速度

        if ((embDataPtr->ctrl == DATA_NULL) || (embDataPtr->ctrl == DATA_END))
        {
            break;
        }
        else
        {
            curDataPtr = embDataPtr;
            for (i=j; i<stepsize; i++)
            {
                if ((curDataPtr->ctrl == DATA_NULL) || (curDataPtr->ctrl == DATA_END))
                {
                    mintpps = minpps;	// 简化处理，直接降速到最低
                    break;
                }

                temp = mintpps;

                // 得到当前数据需要的速度
                if (curDataPtr->ctrl == embDataPtr->ctrl) 			// 数据类型相同
                {
                    if (abs(curDataPtr->dr) > slowAngle)			// 角度差大于降速角度，需要降速
                    {
                        temp = minpps;	// 简化处理，直接降速到最低
                    }
                    else
                    {
                        // 计算本针步最大允许速度
                        // 用XY的速度变化差值限制
                        if (curDataPtr->len != 0)
                        {
                            if (geted != 0)
                            {
                                odx = dx;
                                ody = dy;
                                olen = len;
                            }

                            dx = curDataPtr->dx;
                            dy = curDataPtr->dy;
                            len = curDataPtr->len;

                            if (geted == 0)
                            {
                                odx = dx;
                                ody = dy;
                                olen = len;
                                geted = 1;
                            }

                            mdx = abs(dx*olen - odx*len);
                            mdy = abs(dy*olen - ody*len);
                            mdxy = mdx;
                            if (mdxy < mdy)
                            {
                                mdxy = mdy;
                            }

                            if (mdxy != 0)
                            {
                                temp = minchgpps * len * olen / mdxy;
                            }
                        }
                    }
                }
                else
                {
                    // 不同类型，直接降速到最低
                    mintpps = minpps;	// 目标速度
                    break;
                }

                if (mintpps > temp)		// 最小速度大于当前计算速度
                {
                    mintpps = temp;		// 开始降速
                }
                if (mintpps < minpps)
                {
                    mintpps = minpps;
                    break;
                }

                if (decCount > curDataPtr->len)
                {
                    decCount -= curDataPtr->len;
                }
                else
                {
                    decCount = 0;
                    break;
                }

                curDataPtr++;
            }
        }

        curmaxpps.buf32 = mintpps;
        memcpy(&embDataPtr->rev,&curmaxpps.buf32,4);
        embDataPtr++;
    }
    return 0;
}

//-----------------------------------------------------

int EmbData::setRotate(int dr)
{
    double rr = (dr * PI / 180) * 10000; //转换为弧度

    if (dr == 0 || dr == 360)
    {
        return 0;
    }

    double angle, sina, cosa;

#if (1)
    // 因为计算三角函数有问题，现在只支持 1度，10度，90度
    switch(dr)
    {
    case 1:
        sina = 0.01745240643728351281941897851632;
        cosa = 0.99984769515639123915701155881391;
        break;
    case 10:
        sina = 0.17364817766693034885171662676931;
        cosa = 0.98480775301220805936674302458952;
        break;
    case 90:
        sina = 1;
        cosa = 0;
        break;
    case -1:
        sina = -0.01745240643728351281941897851632;
        cosa = 0.99984769515639123915701155881391;
        break;
    case -10:
        sina = -0.17364817766693034885171662676931;
        cosa = 0.98480775301220805936674302458952;
        break;
    case -90:
        sina = -1;
        cosa = 0;
        break;
    default:
        angle = (dr * PI) / 180.0;
        sina = (double)qSin(angle);
        cosa = (double)qCos(angle);
        break;
    }

#else

    angle = (dr * PI) / 180.0;
    sina = (double)qSin(angle);
    cosa = (double)qCos(angle);
#endif


    // 文件头
    const QByteArray & ary = m_embAbsData;
    int size = ary.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int datasize = size - sizeof(DataDs16FileHead);
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("dat data size err");
        return -1;
    }
    DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());

    //beginR的旋转
    double br = pDsHead->beginR + rr;
    while (br > 2*PI * 10000)
    {
        br -= 2*PI * 10000;
    }
    while (br < -2*PI * 10000)
    {
        br += 2*PI * 10000;
    }
    pDsHead->beginR = br;

    DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;

    // 数据旋转
    for (int j = 0; j < stepsize; j++)
    {
        // 变换前点坐标
        double ax = absDataPtr->ax;
        double ay = absDataPtr->ay;
        double ar = absDataPtr->ar + rr;

        while (ar > 2*PI * 10000)
        {
            ar -= 2*PI * 10000;
        }
        while (ar < -2*PI * 10000)
        {
            ar += 2*PI * 10000;
        }
        // 变换后点的坐标
        double rax = (ax*cosa - ay*sina);
        double ray = (ax*sina + ay*cosa);

        absDataPtr->ax = rax;
        absDataPtr->ay = ray;
        absDataPtr->ar =  ar;
        absDataPtr++;
    }

    m_editedflag = 1;

    return 1;
}

//此函数转换传入的绝对坐标值，是否取镜像及反复时数据之间的间距
void EmbData::convertAbsDat(QByteArray &dat, int mirror)
{
    //无镜像、xy间距、角度旋转、缩放比例都为0时数据无需转换
    if(mirror == 0 &&
            m_spaceX == 0 &&
            m_spaceY == 0 )
    {
        return;
    }

    int size = dat.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("data less then head size");
        return;
    }
    DataDs16FileHead * pDsHead = (DataDs16FileHead *)(dat.data());

    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("dat dataBegin err");
        return;
    }
    int stepsize = datasize/sizeof(DsAbsItem);
    if (stepsize <= 0)
    {
        qDebug("dat data size err");
        return;
    }
    DsAbsItem * pData = (DsAbsItem *)(dat.data() + sizeof(DataDs16FileHead));
    DsAbsItem * absDataPtr = pData;
    //--------

    //镜像数值不为0---开始
    // mirror 0, 无镜像; 1, 水平镜像; 2, 垂直镜像; 3, 水平和垂直镜像
    int mirrorx = 1;
    int mirrory = 1;
    int mirrorr = 1;

    if(mirror == 1 || mirror == 3)
    {
        mirrorx = -1;
        mirrorr = -1;
    }
    if(mirror == 2 || mirror == 3)
    {
        mirrory = -1;
        mirrorr = -1;
    }

    // 镜像文件头转换
    if(mirror != 0)
    {
        pDsHead->beginX = pDsHead->beginX * mirrorx;
        pDsHead->beginY = pDsHead->beginY * mirrory;
    }

    // 镜像或列表间距不为0
    if(mirror != 0 || m_spaceX != 0 || m_spaceY != 0)
    {
        //图形先居中，起始点在加上偏移
        int centerx = (m_maxX + m_minX)/2;
        int centery = (m_maxY + m_minY)/2;

        int rx = (pDsHead->beginX - centerx) * mirrorx;
        int ry = (pDsHead->beginY - centery) * mirrory;

        int beginx = rx + centerx;
        int beginy = ry + centery;

        //用下面两行代码，否则反复方式为Y轴对称或XY对称时不对
        pDsHead->beginX = beginx + m_spaceX;
        pDsHead->beginY = beginy + m_spaceY;
    }
    //镜像数值不为0---结束

    absDataPtr = pData;

    //镜像有变换时运动步才转换
    double dx, dy, dr;

    if(mirror != 0)
    {
        for (int i = 0; i < stepsize; i++)
        {
            // 读入一个针步数据
            dx = absDataPtr->ax;
            dy = absDataPtr->ay;
            dr = absDataPtr->ar;

            //镜像不为0
            if(mirror != 0)
            {
                dx = dx * mirrorx;
                dy = dy * mirrory;
                dr = dr * mirrorr;
            }

            absDataPtr->ax = dx;
            absDataPtr->ay = dy;
            absDataPtr->ar = dr;

            absDataPtr++;
        }
    }

    return;
}

int EmbData::calcLine(double x0, double y0, double x1, double y1, s16 step, QByteArray &absAry, DsAbsItem item)
{
    DsAbsItem absItem;
    memcpy(&absItem,&item,sizeof(DsAbsItem));

    s32 dx, dy;
    double length;
    double tmp;
    int count;
    int i;
    double stepx, stepy;
    double sx, sy;
    int actx, acty;
    double k;

    if(x0 == x1 && y0 == y1)
    {
        return 0;
    }

    if(x0 > x1)
    {
        sx = -1.0;				// x反向
    }
    else
    {
        sx = 1.0;
    }

    if(y0 > y1)
    {
        sy = -1.0;				// y反向
    }
    else
    {
        sy = 1.0;
    }

    // 开始分割针步
    length = sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));

    tmp = length/step;		/* 实际针步数 */
    count = floor(tmp);		/* 最少整针步数 */

    if (tmp - count > 0.01)
    {
        count += 1;
    }

    if (count == 0 && length > 0)	// 短直线
    {
        count = 1;
    }

    tmp = 0;
    actx = x0;
    acty = y0;

    if (x1 != x0 && y1 == y0)				// 横直线
    {
        for (i = 0; i < count; i++)
        {
            tmp = ((i+1)*(length)/count)*sx+x0;	// 实际针步

            stepx = tmp - actx;
            dx = (s32)(stepx+0.5*sx);
            dy = 0;
            actx += dx;

            absItem.ax = actx;
            absItem.ay = y0;
            absAry.append((char*)&absItem,sizeof(DsAbsItem));
        }
    }
    else if (x1 == x0 && y1 != y0)			// 竖直线
    {
        for (i = 0; i < count; i++)
        {
            tmp = ((i+1)*(length)/count)*sy + y0;	// 实际针步

            stepy = tmp - acty;

            dx = 0;
            dy = (s32)(stepy+0.5*sy);
            acty += dy;

            absItem.ax = x0;
            absItem.ay = acty;
            absAry.append((char*)&absItem,sizeof(DsAbsItem));
        }
    }
    else if(x1 != x0 && y1 != y0)			 // 任意斜线
    {
        k = (y1-y0)/(x1-x0);
        for (i = 0; i < count; i++)
        {
            tmp = ((i+1)*(length)/count);

            stepx = fabs(tmp*cos(atan(k)))*sx + x0;	// 实际针步x
            stepy = fabs(tmp*sin(atan(k)))*sy + y0;	// 实际针步y

            dx = (s32)(stepx-actx+0.5*sx);
            dy = (s32)(stepy-acty+0.5*sy);

            actx += dx;
            acty += dy;

            absItem.ax = actx;
            absItem.ay = acty;
            absAry.append((char*)&absItem,sizeof(DsAbsItem));
        }
    }
    else
    {
        printf("what's this?\n");
    }

    return count;
}

//花版的定位点为绝对坐标数据点，起始点为相对于定位点的相对坐标点，第一针为相对于起始点的坐标点
//有的花版起始点有偏移量，第一针偏移量为0，有的花版起始点偏移量为0，第一针有偏移量
//所以ds16文件头定位点坐标就是花版中的定位点，起始点坐标为花版中的定位点坐标+起始点坐标+第一针的坐标，同时ds16数据的第一针坐标偏移应置为0
//生成DS16数据
int EmbData::createEmbDs16FromAbs()
{
    qDebug()<<__FUNCTION__;
#if(0)
    QString ds16FilePath = m_filePath + ".ds16";
    QFile file(ds16FilePath);

    if(file.exists())//存在ds16文件
    {
        if(!file.open(QIODevice::ReadOnly))
        {
            qDebug() << "open file fail when read, path =" << m_filePath;
            return -1;
        }

        m_embDs16Data = file.readAll();
        file.close();

        if(m_embDs16Data.size() <= 0)
        {
            return -1;
        }

        memcpy(m_pEmbDs16Head, m_embDs16Data.data(), sizeof(DataDs16FileHead));   // 文件名称

        m_minX = m_pEmbDs16Head->minX;
        m_maxX = m_pEmbDs16Head->maxX;
        m_minY = m_pEmbDs16Head->minY;
        m_maxY = m_pEmbDs16Head->maxY;
        m_beginX = m_pEmbDs16Head->beginX;
        m_beginY = m_pEmbDs16Head->beginY;

        m_editedflag = 0;

        return 0;
    }
#endif

    if (m_editedflag != 0)
    {
        m_minX = S32_MAX;
        m_maxX = S32_MIN;
        m_minY = S32_MAX;
        m_maxY = S32_MIN;

        m_embDs16Data.clear();

        QString name;

        QByteArray tgtdsdat;
        tgtdsdat.clear();

        u8 ctrlByte;
        u8 attrByte;
        WORD actionWord;	//附加动作
        s32 dx, dy, dr;
        u16 len;
        double ax, ay, ar;
        int actx, acty, actr;
        int ddx, ddy,ddr;

        int beginx, beginy, beginr, anchorx, anchory;
        int minx, miny, maxx, maxy;
        int colornum = 1;
        int jumpNeedleNum = 0;//跳针数
        actx = 0;
        acty = 0;
        actr =0;
        beginx = 0;
        beginy = 0;
        beginr = 0;
        anchorx = anchory = 0;

        int totalstepsize = 0;
        memset(m_pEmbDs16Head,0,sizeof(DataDs16FileHead));

        const QByteArray & ary = m_embAbsData;
        int size = ary.size();
        if (size <= (int)sizeof(DataDs16FileHead))
        {
            qDebug("ary data less then head size");
            return -1;
        }
        DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ary.data());
        //fileId = pDsHead->fileid;

        int datasize = size - sizeof(DataDs16FileHead);
        if (datasize <= 0)
        {
            qDebug("absdat dataBegin err");
            return -1;
        }
        int stepsize = datasize/sizeof(DsAbsItem);
        if (stepsize <= 0)
        {
            qDebug("absdat data size err");
            return -1;
        }
        DsAbsItem * pData = (DsAbsItem *)(ary.data() + sizeof(DataDs16FileHead));
        DsAbsItem * absDataPtr = pData;  //中间数据针步
        //-----

        // 文件名称
        QString str = QString::fromLocal8Bit(pDsHead->fileName);
        name = str;
        //str.sprintf("%s", pDsHead->fileName);
        //name += " ";
        //name += str;

        minx = absDataPtr->ax;
        maxx = absDataPtr->ax;
        miny = absDataPtr->ay;
        maxy = absDataPtr->ay;

        // 数据区
        qDebug()<<"stepsize:"<<stepsize;
        for (int j = 0; j < stepsize; j++)
        {
            Ds16Item ds16Item;
            memset(&ds16Item,0,sizeof(Ds16Item));//清空ds16针步

            ctrlByte = absDataPtr->ctrl;
            attrByte = absDataPtr->attr;//绝对数据的属性字节
            actionWord = absDataPtr->action;

            ax = absDataPtr->ax;//绝对数据的X位置
            ay = absDataPtr->ay;
            ar = absDataPtr->ar;

            // 轮廓
            if (minx > ax) { minx = ax; }
            if (maxx < ax) { maxx = ax; }
            if (miny > ay) { miny = ay; }
            if (maxy < ay) { maxy = ay; }

            if (j == 0)//第一针
            {
                beginx = ax;
                beginy = ay;
                beginr = ar;
                actx = ax;
                acty = ay;
                actr = ar;
                anchorx = pDsHead->anchorX;
                anchory = pDsHead->anchorY;

                ddx = 0;
                ddy = 0;
                //让ddr等于0，因为在datafiledsr中将beginR置为0而非第一针的角度，所以不应该用 absDataPtr->ar - pDsHead->beginR
                //如果beginR等于第一针的角度，那么第一针的ddr就应该是0
                ddr = 0;

                //过滤掉空针
                if(ddx== 0 && ddy == 0)
                {
                    actx += ddx;
                    acty += ddy;
                    actr += ddr;
                    absDataPtr++;

                    continue;
                }
            }
            else
            {
                ddx = ax - actx;
                ddy = ay - acty;
                ddr = ar -actr;
            }

            if( ctrlByte == DATA_END    ||
                    ctrlByte == DATA_PAUSE  ||
                    ctrlByte == DATA_CHGND  ||
                    ctrlByte == DATA_CUTTRD ||
                    ctrlByte == DATA_ANGLE ||
                    ctrlByte == DATA_SYNCOFST ||     //  新添
                    0 )
            {
                ddx = 0;
                ddy = 0;
                ddr = 0;
            }

            dx = ddx;
            dy = ddy;
            dr = ddr;

            actx += ddx;
            acty += ddy;
            actr += ddr;

            while (dr < -PI10000)
            {
                dr += PI20000;
            }
            while (dr > PI10000)
            {
                dr -= PI20000;
            }

            if ( 0 && (ctrlByte == DATA_END || ctrlByte == DATA_NULL))
            {
                qDebug()<< "增加剪线" <<j;
                dx = dy = dr = len = 0;
                // 增加剪线
                ds16Item.ctrl = DATA_CUTTRD;
                ds16Item.attr = 0;
                ds16Item.action[0] = 0;
                ds16Item.action[1] = 0;
                ds16Item.dx = dx;
                ds16Item.dy = dy;
                ds16Item.dr = dr;
                ds16Item.len = len;
                memset(ds16Item.rev,0,sizeof(ds16Item.rev));

                tgtdsdat.append((char*)(&ds16Item), sizeof(Ds16Item));
                totalstepsize++;
            }


            //剪线码必须有，否则单个缝纫完成会停顿 飞梭机-hhy
            if (g_emMacType == MACHINE_MULTINEEDLEROTARY && (ctrlByte == DATA_END || ctrlByte == DATA_NULL))
            {
                qDebug()<< "增加剪线" <<j;
                dx = dy = dr = len = 0;
                // 增加剪线
                ds16Item.ctrl = DATA_CUTTRD;
                ds16Item.attr = 0;
                ds16Item.action[0] = 0;
                ds16Item.action[1] = 0;
                ds16Item.dx = dx;
                ds16Item.dy = dy;
                ds16Item.dr = dr;
                ds16Item.len = len;
                memset(ds16Item.rev,0,sizeof(ds16Item.rev));

                tgtdsdat.append((char*)(&ds16Item), sizeof(Ds16Item));
                totalstepsize++;
            }

            //分割针步
            double maxStep = 800.0;
            if (g_emMacType == MACHINE_FLYFLATCUTTING)
            {
                maxStep = 1000.0;
            }
            //如果dx或dy数值太大时，平方会超出double范围，所以先都除以100再乘以10000
            double xyLen = sqrt((dx/100.0*dx/100.0)*10000.0+ (dy/100.0*dy/100.0)*10000.0);
            //if( 0 && xyLen > maxStep && ctrlByte == DATA_SEWING)
            if(xyLen > maxStep)
            {
                s16 addx,addy;
                addx = addy = 0;
                //分割针步
                double splitVal = 400.0;//分割针步为400
                if (g_emMacType == MACHINE_FLYFLATCUTTING)
                {
                    splitVal = 500.0;
                }

                s32 stepNum = xyLen / splitVal;//拆分几步
                double lastStep = (double)((int)xyLen % (int)splitVal);
                double addStep = lastStep / stepNum;

                double stepX = 0;
                double stepY = 0;
                double stepDr = 0;
                for(int m = 0; m < stepNum; m++)
                {
                    stepX = 0;
                    stepY = 0;
                    stepDr = 0;
                    memset(&ds16Item,0,sizeof(Ds16Item));//初始化结构体

                    stepX = dx * splitVal / xyLen + dx * addStep / xyLen;
                    stepY = dy * splitVal / xyLen + dy * addStep / xyLen;

                    if(m == 0)
                    {
                        stepDr = dr;
                    }

                    ds16Item.dx = qRound(stepX);//四舍五入
                    ds16Item.dy = qRound(stepY);

                    if (m == stepNum-1)
                    {// 最后一针,消除累计误差
                        ds16Item.dx = dx - addx;
                        ds16Item.dy = dy - addy;
                    }
                    else
                    {
                        addx += ds16Item.dx;
                        addy += ds16Item.dy;
                    }

                    ds16Item.ctrl = ctrlByte;
                    len = sqrt(ds16Item.dx*ds16Item.dx + ds16Item.dy*ds16Item.dy);
                    ds16Item.attr = attrByte;
                    ds16Item.action[0] = 0;
                    ds16Item.action[1] = 0;
                    ds16Item.dr = stepDr;
                    ds16Item.len = len;
                    memset(ds16Item.rev,0,sizeof(ds16Item.rev));
                    tgtdsdat.append((char*)(&ds16Item), sizeof(Ds16Item));
                    totalstepsize++;
                }
            }
            else
            {
                //粗线布线机,赋len的长度
                if((ctrlByte == DATA_SYNCOFST) && (g_emMacType == MACHINE_THICK_WIRING))
                {
                    memset((char*)&ds16Item,0,sizeof(ds16Item));
                    ds16Item.ctrl = DATA_SYNCOFST;
                    ds16Item.len = m_splitLen;
                }
                else
                {
                    len = sqrt(dx*dx + dy*dy);
                    ds16Item.ctrl = ctrlByte;
                    ds16Item.attr = attrByte;

                    memcpy(ds16Item.action,&actionWord,sizeof(actionWord));

                    ds16Item.dx = dx;
                    ds16Item.dy = dy;
                    ds16Item.dr = dr;
                    ds16Item.len = len;
                    memset(ds16Item.rev,0,sizeof(ds16Item.rev));
                }

                if(dx == 0 && dy ==0 && dr == 0 && ctrlByte == DATA_DRAWING && g_emMacType == MACHINE_FLYFLATCUTTING)
                {
                    //过滤无效数据
                    qDebug()<<"erro data";
                }
                else
                {
                    tgtdsdat.append((char*)(&ds16Item), sizeof(Ds16Item));//ds16针步
                    totalstepsize++;
                }
            }

            if (ctrlByte == DATA_CHGND)
            {
                colornum++;
            }

            if (ctrlByte == DATA_OFFSET)
            {
                jumpNeedleNum++;//跨步总数加1
            }

            absDataPtr++;
        }

        if (m_minX > minx) { m_minX = minx; }
        if (m_minX > maxx) { m_minX = maxx; }
        if (m_maxX < minx) { m_maxX = minx; }
        if (m_maxX < maxx) { m_maxX = maxx; }
        if (m_minY > miny) { m_minY = miny; }
        if (m_minY > maxy) { m_minY = maxy; }
        if (m_maxY < miny) { m_maxY = miny; }
        if (m_maxY < maxy) { m_maxY = maxy; }


        if(g_emMacType == MACHINE_MULTINEEDLEROTARY)
        {
            angleCorrection(tgtdsdat);              // 角度修正 "x/y+-"版本 by刚哥
            cornerAddNeedleStep(tgtdsdat);          // 拐角分割针步/拐角增加针步
        }

        // 针数
        int newstepnum = tgtdsdat.size() / sizeof(Ds16Item);

        if (newstepnum > 0)
        {
            // 修改文件头
            int namelen = name.size();
            if (namelen > HEAD_NAME_STR_LEN)
            {
                namelen = HEAD_NAME_STR_LEN;
            }

            QByteArray array = name.toLocal8Bit().data();
            int asize = array.length();
            memcpy(m_pEmbDs16Head->fileName, array, asize);   // 文件名称
            m_pEmbDs16Head->dataSize = newstepnum*sizeof(Ds16Item);    // 数据字节数
            m_pEmbDs16Head->itemNums = newstepnum;                    // 数据项个数
            m_pEmbDs16Head->bytesPerItem = sizeof(Ds16Item);           // 每项占的字节数
            m_pEmbDs16Head->bytesPerBlk = MAX_EXDP_LEN;               // 数据内容划分块大小
            m_pEmbDs16Head->dataChecksum = calcCheckSum32((u8 *)(tgtdsdat.data()) , m_pEmbDs16Head->dataSize);	// 数据累加校验和
            m_pEmbDs16Head->checkCrc = calcCrc16((u8 *)(m_pEmbDs16Head), HEAD_FIX_INFO_LEN); // 前面6个字段的CRC校验，（6个字段分别为：文件名称，字节数，项个数，每项字节数，每块字节数，数据累加和的CRC校验值）
            m_pEmbDs16Head->fileid = m_pEmbDs16Head->checkCrc;

            m_pEmbDs16Head->anchorX = anchorx;            // 定位点坐标X
            m_pEmbDs16Head->anchorY = anchory;            // 定位点坐标Y, 设置为0，作为基准
            m_pEmbDs16Head->beginX = beginx;              // 数据起点坐标X
            m_pEmbDs16Head->beginY = beginy;              // 数据起点坐标Y
            m_pEmbDs16Head->beginR = beginr;              // 数据起点坐标R  //-rq
            m_pEmbDs16Head->minX = m_minX;
            m_pEmbDs16Head->maxX = m_maxX;
            m_pEmbDs16Head->minY = m_minY;
            m_pEmbDs16Head->maxY = m_maxY;                // 轮廓范围，使用重新计算之后的值
            //中间数据的文件头

            // 添加文件头
            m_embDs16Data.append((char*)m_pEmbDs16Head, sizeof(DataDs16FileHead));//ds16头文件存在ds16中
            // 添加文件数据
            m_embDs16Data.append(tgtdsdat);
        }

#if(1)
        //保存成ds16文件
        QString ds16FilePath = m_filePath + ".ds16";
        QFile file(ds16FilePath);

        if(file.exists())//存在ds16文件
        {
            QFile::remove(ds16FilePath);
        }

        if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
        {
            qDebug() << "open file fail when wirte, path =" << m_filePath;
            return -1;
        }
        else
        {
            file.write(m_embDs16Data);
            file.close();
        }
#endif
    }

    m_editedflag = 0;

    return 0;
}

int EmbData::reCalcDataChecksum()
{
    return 0;
}

//绘制针数索引的跟踪笔
void EmbData::drawNeedleIdxPen(int x, int y, QPainter &painter)
{
    //贴图的xy和画笔的xy值相同
    m_penX = x;
    m_penY = y;

    m_penPix = m_canvas.copy(x-20,y-30,40,40);//复制画笔区域未绘制笔之前的图像

    QPen pen;
    QColor color;

    //绘制深灰色画笔
    pen.setWidth(2);
    color.setRgb(60,60,60);//深灰色
    pen.setColor(color);
    painter.setPen(pen);

    painter.drawLine(x-4, y-28, x-4, y-8);//画左"|"
    painter.drawLine(x+4, y-28, x+4, y-8); //画右"|"
    painter.drawEllipse(x-1, y-10, 2, 2);//画中心"°"
    painter.drawLine(x-4, y-8, x, y);//画左"\"(笔尖)
    painter.drawLine(x+4, y-8, x, y); //画右"/"(笔尖)

    //绘制深红色画笔
    pen.setWidth(1);
    color.setRgb(174,60,64);//深红色
    pen.setColor(color);
    painter.setPen(pen);

    painter.drawLine(x-3, y-28, x-3, y-8);//画左"|"
    painter.drawLine(x+5, y-28, x+5, y-8); //画右"|"
    painter.drawEllipse(x-2, y-12, 3, 3);//画中心"°"
    painter.drawLine(x-3, y-8, x, y);//画左"\"(笔尖)
    painter.drawLine(x+5, y-8, x, y); //画右"/"(笔尖)
}

void EmbData::drawFork(int x, int y, QPainter &painter)
{
    //贴图的xy和画笔的xy值相同
    m_penX = x;
    m_penY = y;

    m_penPix = m_canvas.copy(x-20,y-30,40,40);//复制画笔区域未绘制笔之前的图像

    QPen pen;
    QColor color;

    //绘制深灰色画笔
    pen.setWidth(2);
    color.setRgb(228,42,48);
    pen.setColor(color);
    painter.setPen(pen);

    painter.drawLine(x-8, y-8, x-3, y-3);//   \上一半
    painter.drawLine(x+8, y-8, x+3, y-3);//   /上一半

    painter.drawLine(x+3, y+3, x+8, y+8);
    painter.drawLine(x-3, y+3, x-8, y+8);
}

/**
 * @brief 绘制多头机的跟踪标致
 */
void EmbData::drawFork(int x, int y, QPainter &painter, int index)
{
    m_penPoint[index].setX(x);
    m_penPoint[index].setY(y);

    m_penHeadPix[index] = m_canvas.copy(x-20,y-30,40,40);//复制画笔区域未绘制笔之前的图像

    QPen pen;
    QColor color;

    //绘制深灰色画笔
    pen.setWidth(2);
    color.setRgb(228,42,48);
    pen.setColor(color);
    painter.setPen(pen);

    painter.drawLine(x-8, y-8, x-3, y-3);//   \上一半
    painter.drawLine(x+8, y-8, x+3, y-3);//   /上一半

    painter.drawLine(x+3, y+3, x+8, y+8);
    painter.drawLine(x-3, y+3, x-8, y+8);
}

//擦除针数索引的跟踪笔
void EmbData::eraseNeedleIdxPen(QPainter &painter)
{
    //贴图的xy和画笔的xy值相同
    painter.drawPixmap(m_penX-20,m_penY-30,m_penPix);
}

void EmbData::eraseNeedleIdxPen(QPainter &painter, int index)
{
    painter.drawPixmap(m_penPoint[index].x()-20,m_penPoint[index].y()-30,m_penHeadPix[index]);
}

void EmbData::getCurvePointFillLine(QList<DsAbsItem> &inList, double indRunLen, QList<DsAbsItem> &outList)
{
    DsAbsItem dPoint1, dPoint2, dPoint3;
    double dTatol, dLen1, dLen2, dSpace;
    long lSum, lCount;

    //计算总的线段长
    int iCountPoint = inList.size();
    if(iCountPoint <= 0)
    {
        return;
    }

    getTotalDistanceFillLine(&inList, dTatol);
    if(dTatol == 0)
        return;

    lSum = (long)round(dTatol / indRunLen + 0.1667);
    dSpace = dTatol / (double)lSum;
    if(lSum == 0)
        lSum = 1;

    dPoint1 = inList[0];
    outList.append(dPoint1);//添加第一个点
    dPoint2 = dPoint1;

    dLen1 = dSpace;
    dLen2 = 0;
    int i = 0;
    for(lCount = 0; lCount < lSum; lCount++)
    {
        while(i < inList.size()-1 && dLen2 < dLen1)
        {
            dLen1 -= dLen2;
            dPoint1 = dPoint2;
            i++;
            dPoint2 = inList[i];
            dLen2 = sqrt((dPoint1.ax - dPoint2.ax) * (dPoint1.ax - dPoint2.ax) + (dPoint1.ay - dPoint2.ay) * (dPoint1.ay - dPoint2.ay));
        }
        if(dLen1 < dLen2)
        {
            getPointInSectFillLine(dPoint1, dPoint2, dLen1, dPoint3);
        }
        else
        {
            dPoint3 = dPoint2;
        }
        outList.append(dPoint3);
        dLen2 -= dLen1;
        dLen1 = dSpace;
        dPoint1 = dPoint3;
    }
}

int EmbData::getTotalDistanceFillLine(QList<DsAbsItem> *pPointList, double &dTotal)
{
    DsAbsItem dPoint, dNext;
    double d;
    dTotal = 0;
    int i = 0;
    long lSum = (long)pPointList->count();
    if(lSum > 1)
    {
        while(i < pPointList->size())
        {
            dPoint = pPointList->at(i);
            i++;
            if(i < pPointList->size())
            {
                dNext = pPointList->at(i);
                d =  sqrt((dPoint.ax - dNext.ax) * (dPoint.ax - dNext.ax) + (dPoint.ay- dNext.ay) * (dPoint.ay- dNext.ay));
                dTotal += d;
            }
            else
            {
                break;
            }
        }
    }
    return 0;
}

bool EmbData::getPointInSectFillLine(const DsAbsItem &p1, const DsAbsItem &p2, const double &d, DsAbsItem &outp)
{
    bool bRes;
    DsAbsItem dpoint[3];

    dpoint[0] = p1;
    dpoint[1] = p2;
    dpoint[2] = outp;
    outp = dpoint[1];

    bRes = getPointAtSect(dpoint[0], dpoint[1], d, dpoint[2]);
    outp.ax = dpoint[2].ax;
    outp.ay = dpoint[2].ay;

    return bRes;
}

bool EmbData::getPointAtSect(const DsAbsItem &p1, const DsAbsItem &p2, const double &d, DsAbsItem &outp)
{
    double s = sqrt((p1.ax - p2.ax) * (p1.ax - p2.ax) + (p1.ay - p2.ay) * (p1.ay - p2.ay));
    if(fabs(s) < ZERO)
    {
        if(d < ZERO)
        {
            outp.ax = p1.ax;
            outp.ay = p1.ay;
        }
        return false;
    }
    outp.ax = (p2.ax - p1.ax) * d / s + p1.ax;
    outp.ay = (p2.ay - p1.ay) * d / s + p1.ay;

    return true;
}

//设置视图尺寸(透明背景)
int EmbData::setViewInfo(int width, int height)
{
    //    if (m_viewWidth != width ||
    //        m_viewHight != height)
    {
        if (width <= EMB_PREVIEW_SIDE*2 || height <= EMB_PREVIEW_SIDE*2)
        {
            return -1;
        }
        m_viewWidth = width;
        m_viewHight = height;
        m_canvas = QPixmap(m_viewWidth, m_viewHight);
        m_canvas.fill(Qt::transparent);//用透明色填充
        //memset(m_canvas.bits(), 0x00, m_canvas.byteCount());
    }
    return 0;
}

//设置视图(带背景图片背景)
void EmbData::setViewInfo(QPixmap pix)
{
    m_canvas = pix;
}

//重置数据
void EmbData::setEmbData(int type, int redraw)
{
    m_type = type;
    createDispFromEmbDs16Dat(m_embDs16Data);
    if (redraw != 0)
    {
        drawImageByDispFile();
    }
}

void EmbData::setDispMode(EmbData::DISP_MODE dispmode, int redraw)
{
    m_dispMode = dispmode;
    if(redraw != 0)
    {
        drawImageByDispFile();
    }
}

void EmbData::setDrawMode(EmbData::DRAW_MODE drawmode)
{
    m_drawMode = drawmode;
}

//设置进度显示数据
void EmbData::setExecIndex(int index)
{
    m_stitchIndex = index;

    if(g_emMacType == MACHINE_MULTINEEDLEROTARY)
    {
        //实时刷新最后一个图形 针对一个图像反复绣缝的情况
        int num = m_dispDat.size() / sizeof(DispItem);
        num -= m_pEmbDs16Head->itemNums;
        num += index;
        m_stitchIndex = num;
    }

    if (m_dispMode == DISP_EXECING)
    {
        drawImageByDispFile();
    }
}

void EmbData::reDraw()
{
    drawImageByDispFile();
}

//创建显示用的数据（为了快速显示）
int EmbData::createDispFromEmbDs16Dat(QByteArray &ds16dat)
{
    if(m_type == MACHINE_FIVEHEADPRECISIONSEWING)
        return createDispFromEmbDs16DatForHeadInfo(ds16dat);

    DispItem dispItem;
    m_dispDat.clear();//显示绘图用的数据（需要转换）

    //    DsAbsItem absItem;//用于轮廓提取的绝对坐标值
    //    m_ds16ToAbsDat.clear();//用于轮廓提取的绝对坐标值

    m_stitchIndex = 0;
    m_dispIndex = 0;

    // ds16数据
    int size = ds16dat.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("16 data less then head size");
        return -1;
    }
    DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ds16dat.data());
    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("dat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(Ds16Item);
    if (stepsize <= 0)
    {
        qDebug("ds16 data size err");
        return -1;
    }

    Ds16Item * ds16DataPtr;
    Ds16Item * pData = (Ds16Item *)(ds16dat.data() + sizeof(DataDs16FileHead));
    ds16DataPtr = pData;

    // 图形显示区域
    int width = m_canvas.width();//留4个像素的边
    int height = m_canvas.height();//留4个像素的边

    //    if(g_emMacType == MACHINE_DRAWING)
    //    {
    //        width = m_canvas.height();
    //        height = m_canvas.width();
    //    }

    if (width <= EMB_PREVIEW_SIDE*2 || height <= EMB_PREVIEW_SIDE*2)
    {
        qDebug("preview img too small");
        return -1;
    }

    //留边(否则实时跟踪笔会画出界)
    int viewSide = EMB_PREVIEW_SIDE;
    if(m_drawMode == DRAW_PREVIEW)
    {
        viewSide = 20;//预览模式时整区域留20像素绘制(原色显示)
    }
    int dpminx = viewSide;
    int dpmaxx = width - viewSide;
    int dpminy = viewSide;
    int dpmaxy = height - viewSide;

    //1:1显示无需留边
    //    int dpminx = 0;
    //    int dpmaxx = width;
    //    int dpminy = 0;
    //    int dpmaxy = height;

    // 计算缩放系数
    double factor, temp;
    if ((dpmaxx - dpminx) <= 0 || (dpmaxy - dpminy) <= 0)
    {
        return -1;
    }

    factor = (double)(fabs(m_maxX-m_minX)) / (dpmaxx - dpminx);      // 按框尺寸x计算的缩放系数
    temp =   (double)(fabs(m_maxY-m_minY)) / (dpmaxy - dpminy);      // 按框尺寸y计算的缩放系数

    if (temp >= factor)     // 使用较大的缩放系数
    {
        factor = temp;
    }

    m_factor = factor;

    // 计算显示参数，按照图形的实际位置显示（数据坐标零点对应图形中心）
    int dpx = (int)((dpminx+dpmaxx)/2 - ((m_maxX+m_minX)/factor)/2);
    int dpy = (int)((dpminy+dpmaxy)/2 - ((m_maxY+m_minY)/factor)/2);

    // 显示花样图形
    u8 ctrlByte;
    u8 attrByte;
    int dx;
    int dy;
    int dr;

    double datposx, datposy, datposr;
    int curx, cury, curr, prex, prey;
    curx = cury = curr = prex = prey = 0;

    datposx = pDsHead->beginX;
    datposy = pDsHead->beginY;
    datposr = pDsHead->beginR;

    curx = (datposx) / factor + dpx;
    cury = (datposy) / factor + dpy;

    if(g_emMacType == MACHINE_FLYFLATCUTTING ||
            g_emMacType == MACHINE_THICK_WIRING ||
            g_emMacType == MACHINE_FLATCUTTINGMAC)  //  20241223 新加了平板切割机  coco todo
    {
        emb_showDirY = -1;
    }

    if(g_emMacType == MACHINE_MULTINEEDLEROTARY)
    {
        emb_showDirX = -1;
    }

    if(g_emMacType == MACHINE_DRAWING)
    {
        emb_showDirY = -1;//正确为-1
    }

    if (emb_showDirX == -1)
    {
        curx = width - curx;
    }
    if (emb_showDirY == -1)
    {
        cury = height - cury;
    }

    double maxX = S32_MIN;
    double maxY = S32_MIN;
    double minX = S32_MAX;
    double minY = S32_MAX;

    for (int i = 0; i < stepsize; i++)
    {
        prex = curx;
        prey = cury;

        // 读入一个针步数据
        ctrlByte = ds16DataPtr->ctrl;
        attrByte = ds16DataPtr->attr;
        dx = ds16DataPtr->dx;
        dy = ds16DataPtr->dy;
        dr = ds16DataPtr->dr;

        datposx += dx;
        datposy += dy;
        datposr += dr;

        curx = (datposx) / factor + dpx;
        cury = (datposy) / factor + dpy;

        //        if(g_emMacType == MACHINE_DRAWING)
        //        {
        //            s16 bx1 = prex;
        //            s16 by1 = prey;

        //            prex = by1;
        //            prey = -bx1;

        //            s16 ex1 = curx;
        //            s16 ey1 = cury;

        //            curx = ey1;
        //            cury = -ex1;
        //        }

        if (emb_showDirX == -1)
        {
            curx = width - curx;
        }
        if (emb_showDirY == -1)
        {
            cury = height - cury;
        }

        while(datposr >= PI10000)
        {
            datposr -= (PI20000-1);
        }
        while(datposr <= -PI10000)
        {
            datposr += (PI20000-1);
        }

        dispItem.ctrl = ctrlByte;
        dispItem.attr = attrByte;
        dispItem.bx = prex;
        dispItem.by = prey;
        dispItem.ex = curx;
        dispItem.ey = cury;
        dispItem.ar = curr;
        if(g_emMacType == MACHINE_FLATCUTTINGMAC || g_emMacType == MACHINE_FLYFLATCUTTING){ //平板切割颜色
            if(ctrlByte ==DATA_OFFSET) //跨步(偏移)针步另一钟颜色显示
                dispItem.rgb = getJumpedColour();
            else if(ctrlByte ==DATA_EKNIFE2)//蓝色线条是SP3指令--3#刀---右刀
                //                dispItem.rgb = qRgb(0,128,255);
                //------------coco 20250208 更改颜色
                dispItem.rgb = getSewedColour();
            //------------coco 20250208 更改颜色
            else if(ctrlByte ==DATA_EKNIFE1)//绿色线条是SP4指令---4#刀--左刀
                //                dispItem.rgb = qRgb(0x35,0xC0,0x5C);
                //------------coco 20250208 更改颜色
                dispItem.rgb = getSewedColour();
            //------------coco 20250208 更改颜色
            else
                dispItem.rgb = getSewedColour();

        }else{
            if(ctrlByte ==DATA_OFFSET) //跨步(偏移)针步另一钟颜色显示
                dispItem.rgb = getJumpedColour();
            else
                dispItem.rgb = getSewedColour();
        }

        //因坐标系不同，写画机显示时需要左转90度
        if(g_emMacType == MACHINE_DRAWING)
        {
            s16 bx1 = dispItem.bx;
            s16 by1 = dispItem.by;

            dispItem.bx = by1;
            dispItem.by = -bx1;

            if(minX > dispItem.bx)
            {
                minX = dispItem.bx;
            }
            if(minY > dispItem.by)
            {
                minY = dispItem.by;
            }
            if(maxX < dispItem.bx)
            {
                maxX = dispItem.bx;
            }
            if(maxY < dispItem.by)
            {
                maxY = dispItem.by;
            }

            s16 ex1 = dispItem.ex;
            s16 ey1 = dispItem.ey;

            dispItem.ex = ey1;
            dispItem.ey = -ex1;

            if(minX > dispItem.ex)
            {
                minX = dispItem.ex;
            }
            if(minY > dispItem.by)
            {
                minY = dispItem.by;
            }
            if(maxX < dispItem.ex)
            {
                maxX = dispItem.ex;
            }
            if(maxY < dispItem.ey)
            {
                maxY = dispItem.ey;
            }
        }
        //qDebug()<<"dispItem"<<dispItem.bx<<dispItem.by<<dispItem.ex<<dispItem.ey;

        memcpy(&dispItem.action,ds16DataPtr->action,sizeof(dispItem.action));

        m_dispDat.append((char*)(&dispItem), sizeof(DispItem));

        ds16DataPtr++;
    }

    //左转90度后居中显示
    if(g_emMacType == MACHINE_DRAWING)
    {
        QByteArray dispDat;//绘制图形的绝对数据(进行缩放的)
        dispDat.clear();

        factor = (double)(fabs(maxX-minX)) / (dpmaxx - dpminx);      // 按框尺寸x计算的缩放系数
        temp =   (double)(fabs(maxY-minY)) / (dpmaxy - dpminy);      // 按框尺寸y计算的缩放系数

        if (temp >= factor)     // 使用较大的缩放系数
        {
            factor = temp;
        }

        // 计算显示参数，按照图形的实际位置显示（数据坐标零点对应图形中心）
        int dpx = (int)((dpminx+dpmaxx)/2 - ((maxX+minX)/factor)/2);
        int dpy = (int)((dpminy+dpmaxy)/2 - ((maxY+minY)/factor)/2);

        int size = m_dispDat.size() / sizeof(DispItem);
        DispItem* dispStep = (DispItem*)(m_dispDat.data());
        for(int i = 0; i < size; i++)
        {
            dispStep->bx = dispStep->bx/ factor + dpx;
            dispStep->by = dispStep->by/ factor + dpy;
            dispStep->ex = dispStep->ex/ factor + dpx;
            dispStep->ey = dispStep->ey/ factor + dpy;
            dispDat.append((char*)(dispStep), sizeof(DispItem));
            dispStep++;
        }

        m_dispDat.clear();
        m_dispDat.append(dispDat);
    }

    qDebug("CreateDispFromEmbDs16, stepsize=%d", m_dispDat.size() / sizeof(DispItem));

    return 0;
}

/**
 * @brief EmbData::五头机创建绘图数据
 * @param ds16dat
 * @return
 */
int EmbData::createDispFromEmbDs16DatForHeadInfo(QByteArray &ds16dat)
{
    m_headDispDate.clear();

    DataFileDsr dsr;//可能引起栈内存溢出的问题
    dsr.initFile(m_filePath);
    dsr.convertDataToEmbAbs();
    DsrHeadEx62 head = dsr.get62ExHead();
    int StepNum = dsr.getStepNums();
    int maxHSP = findMaxSpHead(head,StepNum);

    Disp_HeadItem dispItem;
    m_dispDat.clear();//显示绘图用的数据（需要转换）

    m_stitchIndex = 0;
    m_dispIndex = 0;

    // ds16数据
    int size = ds16dat.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("16 data less then head size");
        return -1;
    }
    DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ds16dat.data());
    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("dat dataBegin err");
        return -1;
    }
    int stepsize = datasize/sizeof(Ds16Item);
    if (stepsize <= 0)
    {
        qDebug("ds16 data size err");
        return -1;
    }

    Ds16Item * ds16DataPtr;
    Ds16Item * pData = (Ds16Item *)(ds16dat.data() + sizeof(DataDs16FileHead));
    ds16DataPtr = pData;

    // 图形显示区域
    int width = m_canvas.width();//留4个像素的边
    int height = m_canvas.height();//留4个像素的边
    if (width <= EMB_PREVIEW_SIDE*2 || height <= EMB_PREVIEW_SIDE*2)
    {
        qDebug("preview img too small");
        return -1;
    }

    //留边(否则实时跟踪笔会画出界)
    int viewSide = EMB_PREVIEW_SIDE;
    if(m_drawMode == DRAW_PREVIEW)
    {
        viewSide = 20;//预览模式时整区域留20像素绘制(原色显示)
    }
    int dpminx = viewSide;
    int dpmaxx = width - viewSide;
    int dpminy = viewSide;
    int dpmaxy = height - viewSide;

    // 计算缩放系数
    double factor, temp;
    if ((dpmaxx - dpminx) <= 0 || (dpmaxy - dpminy) <= 0)
    {
        return -1;
    }

    factor = (double)(fabs(m_maxX+(maxHSP*10)-m_minX)) / (dpmaxx - dpminx);      // 按框尺寸x计算的缩放系数 五头机加上一个最大值保证绘图不越界
    temp =   (double)(fabs(m_maxY-m_minY)) / (dpmaxy - dpminy);      // 按框尺寸y计算的缩放系数
    // 使用较大的缩放系数
    factor = temp >= factor?temp:factor;
    m_factor = factor;

    // 计算显示参数，按照图形的实际位置显示（数据坐标零点对应图形中心）
    int dpx = (int)((dpminx+dpmaxx)/2 - ((m_maxX+m_minX+(maxHSP*10))/factor)/2);//最大x需要 五头机加上一个最大值保证绘图不越界
    int dpy = (int)((dpminy+dpmaxy)/2 - ((m_maxY+m_minY)/factor)/2);

    // 显示花样图形

    double datposx = pDsHead->beginX;
    double datposy = pDsHead->beginY;

    int curx = (datposx) / factor + dpx;
    int cury = (datposy) / factor + dpy;

    if (emb_showDirX == -1)
    {
        curx = width - curx;
    }
    if (emb_showDirY == -1)
    {
        cury = height - cury;
    }

    for (int i = 0; i < stepsize; i++)
    {
        int prex = curx;
        int prey = cury;

        // 读入一个针步数据
        int dx = ds16DataPtr->dx;
        int dy = ds16DataPtr->dy;
        unsigned short int headSpHndex = ds16DataPtr->action[1] & 0xFF;

        datposx += dx;
        datposy += dy;

        curx = (datposx) / factor + dpx;
        cury = (datposy) / factor + dpy;

        if (emb_showDirX == -1)
        {
            curx = width - curx;
        }
        if (emb_showDirY == -1)
        {
            cury = height - cury;
        }

        dispItem.ctrl = ds16DataPtr->ctrl;
        dispItem.attr = ds16DataPtr->attr;
        dispItem.bx = prex;
        dispItem.by = prey;
        dispItem.ex = curx;
        dispItem.ey = cury;
        dispItem.ar = ds16DataPtr->dr;
        memcpy(&dispItem.action,ds16DataPtr->action,2);
        dispItem.headtable.iswork = head.headEnableSpacing[headSpHndex].iswork;
        dispItem.headtable.distance1_2 = head.headEnableSpacing[headSpHndex].distance1_2;
        dispItem.headtable.distance1_3 = head.headEnableSpacing[headSpHndex].distance1_3;
        dispItem.headtable.distance1_4 = head.headEnableSpacing[headSpHndex].distance1_4;
        dispItem.headtable.distance1_5 = head.headEnableSpacing[headSpHndex].distance1_5;
        dispItem.headtable.distance1_6 = head.headEnableSpacing[headSpHndex].distance1_6;
        dispItem.headtable.distance1_7 = head.headEnableSpacing[headSpHndex].distance1_7;
        dispItem.headtable.distance1_8 = head.headEnableSpacing[headSpHndex].distance1_8;
        if(ds16DataPtr->ctrl ==DATA_OFFSET) //跨步(偏移)针步另一钟颜色显示
            dispItem.rgb = getNoJumpColour();
        else
            dispItem.rgb = getNoSewColour();

        m_headDispDate.append(dispItem);

        ds16DataPtr++;
    }

    qDebug() << "createDispFromEmbDs16DatForHeadInfo"<< "CreateDispFromEmbDs16, stepsize="<< m_headDispDate.size();

    return 0;
}

#define DRAWDR 0

int EmbData::drawImageByDispFile()
{
    if(m_type == MACHINE_FIVEHEADPRECISIONSEWING)
        return drawImageByOneStepLotLine();

    int bx, by, ex, ey, ar;
    bx = by = ex = ey = ar = 0;
    int i;
    u8 ctrlByte;
    DispItem * pDispBuff = (DispItem *)m_dispDat.data();

    int size = m_dispDat.size();
    int stitchCount = size/sizeof(DispItem);

    if (stitchCount <= 0)
    {
        stitchCount = 0;
    }
    if (m_stitchIndex >= stitchCount)
    {
        m_stitchIndex = stitchCount - 1;
    }
    if (m_stitchIndex < 0)
    {
        m_stitchIndex = 0;
    }

    DISP_MODE dispmode = m_dispMode;

    QPainter painter(&m_canvas);

    QRgb rgb;
    QPen pen;

    //笔宽
    pen.setWidth(1);
    rgb = 0;

    if (dispmode == DISP_ALL_NORMAL ||        // 显示所有线迹（原色显示）
            dispmode == DISP_ALL_EXEC   ||        // 显示所有线迹（执行过的显示原色，其余显示灰色）
            0)
    {
        int tenThousand = 0;
        for (i = 0; i < stitchCount; i++)
        {
            tenThousand++;
            if(tenThousand == TENTHOUSANDNEEDLE)
            {
                tenThousand = 0;
                int idx = i / TENTHOUSANDNEEDLE;
                //每十万针主界面加载图片的进度条走一格
                emit siDrawNeedleIdx(idx);
            }

            bx = pDispBuff[i].bx;
            by = pDispBuff[i].by;
            ex = pDispBuff[i].ex;
            ey = pDispBuff[i].ey;
            rgb = pDispBuff[i].rgb;
            ctrlByte = pDispBuff[i].ctrl;

            // 从开始到 m_stitchIndex 显示正常颜色的线迹（执行过），从 m_stitchIndex 结束显示未缝纫颜色线迹（未执行）
            if ((dispmode == DISP_ALL_EXEC) && (i >= m_stitchIndex))
            {
                if(ctrlByte ==DATA_OFFSET) //跨步(偏移)针步另一钟颜色显示
                    rgb = getNoJumpColour();
                else
                {
                    //                    rgb = getNoSewColour();
                    rgb = pDispBuff[i].rgb;
                }
            }

            pen.setColor(rgb);
            painter.setPen(pen);
            painter.drawLine(bx, by, ex, ey);

#if(DRAWDR)
            double len = sqrt((double)(ex-bx)*(double)(ex-bx)+ (double)(ey-by)*(double)(ey-by));

            int mx = len * cos((PI10000-ar)/10000.0);
            int my = len * sin((PI10000-ar)/10000.0);
            QColor color = QColor(Qt::green);
            QPen pen;
            pen.setColor(color);
            painter.setPen(pen);
            painter.drawLine(bx, by, bx+mx, by+my);
            pen.setColor(QColor(Qt::red));
            painter.setPen(pen);
            painter.drawEllipse(bx+mx, by+my,2,2);
#endif
        }

        if (dispmode == DISP_ALL_EXEC && m_stitchIndex < stitchCount)
        {
            //飞梭机将跟踪笔画到最后一个循环开始处
            if(g_emMacType == MACHINE_MULTINEEDLEROTARY)
            {
                int num = m_dispDat.size() / sizeof(DispItem);
                num -= m_pEmbDs16Head->itemNums;
                i = num + m_stitchIndex;
            }
            else
            {
                i = m_stitchIndex;
            }

            i = m_stitchIndex;

            bx = pDispBuff[i].bx;
            by = pDispBuff[i].by;
            drawFork(bx, by, painter);//绘制准星
            m_dispIndex = m_stitchIndex;            // 移动显示指针
        }
    }
    else if (dispmode == DISP_EXECING)   // 刷新部分线迹（缝纫中进度显示）
    {
        //qDebug()<<"m_stitchIndex"<<m_stitchIndex<<"m_dispIndex"<<m_dispIndex;

        if (m_stitchIndex != m_dispIndex)
        {
            eraseNeedleIdxPen(painter);//擦除跟踪笔

            // 显示针迹改变
            if (m_stitchIndex > m_dispIndex && m_stitchIndex < stitchCount)
            {
                i = m_dispIndex;

                while(i < m_stitchIndex)
                {
                    bx = pDispBuff[i].bx;
                    by = pDispBuff[i].by;
                    ex = pDispBuff[i].ex;
                    ey = pDispBuff[i].ey;
                    //                    rgb = pDispBuff[i].rgb;// 显示为原线迹
                    if(pDispBuff[i].ctrl == DATA_OFFSET)
                    {
                        //rgb = qRgb(86,86,86);//飞行平板切割-偏移点显示为灰色
                        rgb =  qRgb(245,245,245);
                    }
                    else if(pDispBuff[i].ctrl == DATA_DRAWING)
                    {
                        rgb = QColor(Qt::red).rgb();//飞行平板切割-记号（画笔）显示为红色
                    }
                    else if(pDispBuff[i].ctrl == DATA_RKNIFE)
                    {
                        rgb = qRgb(0, 206, 209);//飞行平板切割-圆刀显示为蓝绿色
                    }
                    else if(pDispBuff[i].ctrl == DATA_SKNIFE)
                    {
                        rgb = qRgb(154, 205, 50);//飞行平板切割-振刀显示为黄绿色
                    }
                    else if(pDispBuff[i].ctrl == DATA_ANGLE_OLD)//todo
                    {
                        rgb = qRgb(147, 112, 219);//飞行平板切割-拐点显示为深紫色
                    }
                    else
                    {
                        rgb = qRgb(245,245,245);//默认显示为白色
                    }

                    pen.setColor(rgb);
                    painter.setPen(pen);
                    painter.drawLine(bx, by, ex, ey);
                    i++;
                }
            }
            else if (m_stitchIndex < m_dispIndex && m_dispIndex < stitchCount)
            {
                i = m_stitchIndex;

                while(i <= m_dispIndex)        // 显示为未缝纫颜色线迹
                {
                    bx = pDispBuff[i].bx;
                    by = pDispBuff[i].by;
                    ex = pDispBuff[i].ex;
                    ey = pDispBuff[i].ey;
                    ctrlByte = pDispBuff[i].ctrl;

                    if(ctrlByte ==DATA_OFFSET) //跨步(偏移)针步另一钟颜色显示
                        rgb = getNoJumpColour();
                    else if(ctrlByte == DATA_DRAWING)
                    {
                        rgb = QColor(Qt::red).rgb();//飞行平板切割-记号（画笔）显示为红色
                    }
                    else
                    {
                        //rgb = getNoSewColour();
                        rgb = pDispBuff[i].rgb;
                    }

                    pen.setColor(rgb);
                    painter.setPen(pen);
                    painter.drawLine(bx, by, ex, ey);
                    i++;
                }
            }

            i = m_stitchIndex;

            bx = pDispBuff[i].bx;
            by = pDispBuff[i].by;
            drawFork(bx, by, painter);//绘制跟踪笔
            m_dispIndex = m_stitchIndex;            // 移动显示指针
        }
    }
    return 0;
}

#include <bitset>
using namespace std;
/**
 * @brief EmbData::drawImageByOneStepLotLine
 * @return
 * 五头机绘图函数 根据机头间距表信息单步画多条线
 */
int EmbData::drawImageByOneStepLotLine()
{
    int stitchCount = m_headDispDate.size();
    //限制针步数 否则访问溢出
    if (stitchCount <= 0)
    {
        stitchCount = 0;
    }
    if (m_stitchIndex >= stitchCount)
    {
        m_stitchIndex = stitchCount - 1;
    }
    if (m_stitchIndex < 0)
    {
        m_stitchIndex = 0;
    }

    QPainter painter(&m_canvas);
    QRgb rgb;
    QPen pen;

    //笔宽
    pen.setWidth(1);

    if (m_dispMode == DISP_ALL_NORMAL ||        // 显示所有线迹（原色显示）
            m_dispMode == DISP_ALL_EXEC   ||        // 显示所有线迹（执行过的显示原色，其余显示灰色）
            0)
    {
        int tenThousand = 0;
        for (int i = 0; i < stitchCount; i++)
        {
            tenThousand++;
            if(tenThousand == TENTHOUSANDNEEDLE)
            {
                tenThousand = 0;
                int idx = i / TENTHOUSANDNEEDLE;
                //每十万针主界面加载图片的进度条走一格
                emit siDrawNeedleIdx(idx);
            }

            // 从开始到 m_stitchIndex 显示正常颜色的线迹（执行过），从 m_stitchIndex 结束显示未缝纫颜色线迹（未执行）
            rgb = m_headDispDate[i].rgb;

            if ((m_dispMode == DISP_ALL_EXEC) && (i >= m_stitchIndex))
            {
                if(m_headDispDate[i].ctrl ==DATA_OFFSET) //跨步(偏移)针步另一钟颜色显示
                    rgb = getNoJumpColour();
                else
                    rgb = getNoSewColour();
            }

            drawMultiLine(painter,pen,rgb,i);///多机头绘线
        }

        if (m_dispMode == DISP_ALL_EXEC && m_stitchIndex < stitchCount)
        {
            drawMultiTrack(painter);///绘制多机头的跟踪图案
            m_dispIndex = m_stitchIndex;            // 移动显示指针
        }
    }
    else if (m_dispMode == DISP_EXECING)   // 刷新部分线迹（缝纫中进度显示）前进回退的时候
    {
        //qDebug()<<"m_stitchIndex"<<m_stitchIndex<<"m_dispIndex"<<m_dispIndex;

        if (m_stitchIndex != m_dispIndex)
        {

            for(int j = 0; j < headNum; j++)
                eraseNeedleIdxPen(painter,j);///擦除跟踪笔

            // 显示针迹改变
            if (m_stitchIndex > m_dispIndex && m_stitchIndex < stitchCount)
            {
                /// 从小针步增加到大针步
                int i = m_dispIndex;

                while(i < m_stitchIndex)        // 显示为原线迹
                {
                    if(m_headDispDate[i].ctrl ==DATA_OFFSET) //跨步(偏移)针步另一钟颜色显示
                        rgb = getJumpedColour();
                    else
                        rgb = getSewedColour();
                    drawMultiLine(painter,pen,rgb,i);///多机头绘线
                    i++;
                }
            }
            else if (m_stitchIndex < m_dispIndex && m_dispIndex < stitchCount)
            {
                /// 从大针步减少到小针步
                int i = m_stitchIndex;

                while(i <= m_dispIndex)        // 显示为未缝纫颜色线迹
                {
                    rgb = m_headDispDate[i].rgb;
                    drawMultiLine(painter,pen,rgb,i);///多机头绘线
                    i++;
                }
            }

            drawMultiTrack(painter);///绘制多机头的跟踪图案
            m_dispIndex = m_stitchIndex;            // 移动显示指针
        }
    }
    return 0;
}

/**
 * @brief EmbData::findMaxSpHead
 * @param head 机头间距表
 * @param StepNum 跨步数
 * @return 返回机头间距表中用到的最大偏移值
 */
int EmbData::findMaxSpHead(DsrHeadEx62 &head,int StepNum)
{
    int max = 0;
    for(int i = 0 ; i < StepNum;i++){
        bitset<8> iswork(head.headEnableSpacing[i].iswork);
        for(int j = 1; j < headNum; j++)
        {
            if(!iswork.test(j)) // test(i)为0返回false
                continue;
            unsigned short int* row = (unsigned short int*)&head.headEnableSpacing[i];
            unsigned short int space = *(row + j); //向后偏移得到具体大小
            max = max > space ? max : space;
        }
    }
    return max;
}

///
/// \brief 根据机头间距表的iswork字段 选择性的绘制跟踪画笔
///
void EmbData::drawMultiTrack(QPainter &painter)
{
    int bx = m_headDispDate[m_stitchIndex].bx;
    int by = m_headDispDate[m_stitchIndex].by;
    bitset<8> iswork(m_headDispDate[m_stitchIndex].headtable.iswork);

    for(int j = 0; j < headNum; j++){
        if(j==0)//第一个机头不需要偏移
            drawFork(bx, by, painter, j);
        else if(iswork.test(j))///不是第一针，需要计算偏移量
        {
            unsigned short int* row = (unsigned short int*)&m_headDispDate[m_stitchIndex].headtable; // 取到结构体的初始地址
            unsigned short int space = *(row + j); //向后偏移得到具体大小
            space = (space*10)/m_factor; //从实际距离转换为像素，得到最终的偏移像素
            drawFork(bx + space, by, painter, j);
        }
        else
        {
            ///如果下一针不缝了 不需要画跟踪标志，也不需要还原上一针的图像
            ///所以此处将上一针的图像缓存重置，以免把画好的线迹擦除
            m_penHeadPix[j] = QPixmap();
        }

    }
}

///
/// \brief 五头机函数，根据机头间距表信息多机头同时画线
/// \param painter
/// \param pen
/// \param rgb
/// \param index
///
void EmbData::drawMultiLine(QPainter &painter, QPen &pen, QRgb rgb, int index)
{
    int bx = m_headDispDate[index].bx;//begin
    int by = m_headDispDate[index].by;
    int ex = m_headDispDate[index].ex;//end
    int ey = m_headDispDate[index].ey;

    pen.setColor(rgb);
    painter.setPen(pen);
    bitset<8> iswork(m_headDispDate[index].headtable.iswork);


    for(int j = 0; j < headNum; j++){
        if(!iswork.test(j)) // test(i)为0，表示机头不工作，跳过循环
        {
            if(j == 0){//如果是一机头不工作，那么使用黄色线段画出
                painter.save();
                painter.setPen(getNoJumpColour());
                painter.drawLine(bx, by, ex, ey); //机头1 缝纫数据 和原数据一致
                painter.restore();
            }
            continue;
        }

        //缝纫数据
        if(m_headDispDate[index].ctrl ==DATA_SEWING)
        {
            if(j == 0){//机头1
                painter.drawLine(bx, by, ex, ey); //机头1 缝纫数据 和原数据一致
            }
            else
            {
                unsigned short int* row = (unsigned short int*)&m_headDispDate[index].headtable; // 取到结构体的初始地址
                unsigned short int space = *(row + j); //向后偏移得到具体大小
                space = (space*10)/m_factor; //从实际距离转换为像素
                painter.drawLine(bx+space, by, ex+space, ey); //不是机头1的画线时需要偏移
            }
        }
        else{
            painter.drawLine(bx, by, ex, ey);
        }

    }
}

void EmbData::getOneDispDat(QByteArray &ds16dat)
{
    DispItem dispItem;
    // ds16数据
    int size = ds16dat.size();
    if (size <= (int)sizeof(DataDs16FileHead))
    {
        qDebug("16 data less then head size");
        return;
    }
    DataDs16FileHead * pDsHead = (DataDs16FileHead *)(ds16dat.data());
    int datasize = size - sizeof(DataDs16FileHead);
    if (datasize <= 0)
    {
        qDebug("dat dataBegin err");
        return;
    }
    int stepsize = datasize/sizeof(Ds16Item);
    if (stepsize <= 0)
    {
        qDebug("ds16 data size err");
        return;
    }

    Ds16Item * ds16DataPtr;
    Ds16Item * pData = (Ds16Item *)(ds16dat.data() + sizeof(DataDs16FileHead));
    ds16DataPtr = pData;

    double datposx, datposy, datposr;
    int curx, cury, curr, prex, prey;
    curx = cury = curr = prex = prey = 0;

    // 显示花样图形
    u8 ctrlByte;
    u8 attrByte;
    int dx;
    int dy;
    int dr;
    m_oneDispDat.clear();

    m_dispMinX = S32_MAX;
    m_dispMaxX = S32_MIN;
    m_dispMinY = S32_MAX;
    m_dispMaxY = S32_MIN;

    datposx = pDsHead->beginX;
    datposy = pDsHead->beginY;
    datposr = pDsHead->beginR;

    curx = datposx;
    cury = datposy;

    //先得到一个完整的绘制数据
    for (int i = 0; i < stepsize; i++)
    {
        prex = curx;
        prey = cury;

        // 读入一个针步数据
        ctrlByte = ds16DataPtr->ctrl;
        attrByte = ds16DataPtr->attr;
        dx = ds16DataPtr->dx;
        dy = ds16DataPtr->dy;
        dr = ds16DataPtr->dr;

        datposx += dx;
        datposy += dy;
        datposr += dr;

        curx = datposx;
        cury = datposy;

        while(datposr >= PI10000)
        {
            datposr -= (PI20000-1);
        }
        while(datposr <= -PI10000)
        {
            datposr += (PI20000-1);
        }

        dispItem.ctrl = ctrlByte;
        dispItem.attr = attrByte;
        dispItem.bx = prex;
        dispItem.by = prey;
        dispItem.ex = curx;
        dispItem.ey = cury;
        dispItem.ar = curr;

        if (m_dispMinX > dispItem.bx) { m_dispMinX = dispItem.bx; }
        if (m_dispMinX > dispItem.ex) { m_dispMinX = dispItem.ex; }
        if (m_dispMaxX < dispItem.bx) { m_dispMaxX = dispItem.bx; }
        if (m_dispMaxX < dispItem.ex) { m_dispMaxX = dispItem.ex; }
        if (m_dispMinY > dispItem.by) { m_dispMinY = dispItem.by; }
        if (m_dispMinY > dispItem.ey) { m_dispMinY = dispItem.ey; }
        if (m_dispMaxY < dispItem.by) { m_dispMaxY = dispItem.by; }
        if (m_dispMaxY < dispItem.ey) { m_dispMaxY = dispItem.ey; }

        if(ctrlByte == DATA_OFFSET) //跨步(偏移)针步另一钟颜色显示
            dispItem.rgb = getJumpedColour();
        else
            dispItem.rgb = getSewedColour();

        memcpy(&dispItem.action,ds16DataPtr->action,sizeof(dispItem.action));
        m_oneDispDat.append((char*)(&dispItem), sizeof(DispItem));

        ds16DataPtr++;
    }
}

void EmbData::resetLayoutDispDat(unsigned char *arrayNeedle1, unsigned char *arrayNeedle2, unsigned char *arrayNeedle3, int leftRightNeedleSpace,int needlesSpace,int needleLayoutSpace12,int needleLayoutSpace23,int reDat)
{
    m_dispDat.clear();//显示绘图用的数据（需要转换）
    int stepsize = m_oneDispDat.size() / sizeof(DispItem);

    s16 lastNum = 6;//最后一排的循环次数
    int circleNum = 0;//循环次数
    circleNum = (needleLayoutSpace12+needleLayoutSpace23+ (m_maxY - m_minY)*(lastNum+1)) / (m_maxY - m_minY);

    int circleNumMiddle = 0;//循环次数
    circleNumMiddle = (needleLayoutSpace23 + (m_maxY - m_minY)*(lastNum+1)) / (m_maxY - m_minY);

    //根据前中后排的设置，再添加绘制数据
    if(reDat == 0 || reDat == 1)
    {
        //根据前中后排的设置，重置前排数据
        char frontSet[LAYOUTNEEDLENUM*2];
        memset((char*)frontSet,0,sizeof(frontSet));
        for(int i = 0; i < LAYOUTNEEDLENUM; i++)//12个针位设置，对应24根镇，一个针位上有2根针，每根针之间间距为1/2英寸
        {
            if(arrayNeedle1 == NULL)
                break;
            unsigned char val = *(arrayNeedle1+i);
            if(val == NEEDLELEFT)
            {
                frontSet[0+2*i] = 1;
                frontSet[1+2*i] = 0;
            }
            else if(val == NEEDLERIGHT)
            {
                frontSet[0+2*i] = 0;
                frontSet[1+2*i] = 1;
            }
            else if(val == NEEDLEDOUBLE)
            {
                frontSet[0+2*i] = 1;
                frontSet[1+2*i] = 1;
            }
            else if(val == NEEDLENONE)
            {
                frontSet[0+2*i] = 0;
                frontSet[1+2*i] = 0;
            }
        }

        m_dispDatFront.clear();
        DispItem dispItemFront;
        double frontSpace = 0;
        double frontYSpace = 0;
        for(unsigned int i = 0; i < sizeof(frontSet); i++)//12个针位设置，对应24根镇，一个针位上有2根针，每根针之间间距为1/2英寸
        {
            DispItem * pData = (DispItem *)(m_oneDispDat.data());
            char val = frontSet[i];

            if(val == 1)
            {
                for (int j = 0; j < stepsize; j++)
                {
                    dispItemFront = *pData;
                    dispItemFront.bx += frontSpace;
                    dispItemFront.ex += frontSpace;

                    if (m_dispMinX > dispItemFront.bx) { m_dispMinX = dispItemFront.bx; }
                    if (m_dispMinX > dispItemFront.ex) { m_dispMinX = dispItemFront.ex; }
                    if (m_dispMaxX < dispItemFront.bx) { m_dispMaxX = dispItemFront.bx; }
                    if (m_dispMaxX < dispItemFront.ex) { m_dispMaxX = dispItemFront.ex; }
                    //中排和后排无数据时
                    if(m_dispDatMiddle.size() <= 0 && m_dispDatBehind.size() <= 0)
                    {
                        if (m_dispMinY > dispItemFront.by) { m_dispMinY = dispItemFront.by; }
                        if (m_dispMinY > dispItemFront.ey) { m_dispMinY = dispItemFront.ey; }
                        if (m_dispMaxY < dispItemFront.by) { m_dispMaxY = dispItemFront.by; }
                        if (m_dispMaxY < dispItemFront.ey) { m_dispMaxY = dispItemFront.ey; }
                    }

                    m_dispDatFront.append((char*)(&dispItemFront), sizeof(DispItem));
                    pData++;
                }

                //Y方向再循环多次
                for(int m = 0; m < circleNum; m++)
                {
                    DispItem * pData = (DispItem *)(m_oneDispDat.data());
                    frontYSpace = m * (m_maxY - m_minY) + (m_maxY - m_minY);
                    for (int j = 0; j < stepsize; j++)
                    {
                        dispItemFront = *pData;
                        dispItemFront.bx += frontSpace;
                        dispItemFront.ex += frontSpace;
                        dispItemFront.by -= frontYSpace;
                        dispItemFront.ey -= frontYSpace;

                        if (m_dispMinX > dispItemFront.bx) { m_dispMinX = dispItemFront.bx; }
                        if (m_dispMinX > dispItemFront.ex) { m_dispMinX = dispItemFront.ex; }
                        if (m_dispMaxX < dispItemFront.bx) { m_dispMaxX = dispItemFront.bx; }
                        if (m_dispMaxX < dispItemFront.ex) { m_dispMaxX = dispItemFront.ex; }
                        //中排和后排无数据时
                        if(m_dispDatMiddle.size() <= 0 && m_dispDatBehind.size() <= 0)
                        {
                            if (m_dispMinY > dispItemFront.by) { m_dispMinY = dispItemFront.by; }
                            if (m_dispMinY > dispItemFront.ey) { m_dispMinY = dispItemFront.ey; }
                            if (m_dispMaxY < dispItemFront.by) { m_dispMaxY = dispItemFront.by; }
                            if (m_dispMaxY < dispItemFront.ey) { m_dispMaxY = dispItemFront.ey; }
                        }

                        m_dispDatFront.append((char*)(&dispItemFront), sizeof(DispItem));
                        pData++;
                    }
                }
            }
            if(i % 2 == 0)
            {
                frontSpace += leftRightNeedleSpace;
            }
            else
            {
                //frontSpace += leftRightNeedleSpace*3;
                frontSpace = (i-i/2)*needlesSpace;
            }
        }
    }

    if(reDat == 0 || reDat == 2)
    {
        double dispMinY = S32_MAX;
        double dispMaxY = S32_MIN;

        //根据前中后排的设置，重置中排数据
        char middleSet[LAYOUTNEEDLENUM*2];
        memset((char*)middleSet,0,sizeof(middleSet));
        for(int i = 0; i < LAYOUTNEEDLENUM; i++)//12个针位设置，对应24根镇，一个针位上有2根针，每根针之间间距为1/2英寸
        {
            if(arrayNeedle2 == NULL)
                break;
            unsigned char val = *(arrayNeedle2+i);
            if(val == NEEDLELEFT)
            {
                middleSet[0+2*i] = 1;
                middleSet[1+2*i] = 0;
            }
            else if(val == NEEDLERIGHT)
            {
                middleSet[0+2*i] = 0;
                middleSet[1+2*i] = 1;
            }
            else if(val == NEEDLEDOUBLE)
            {
                middleSet[0+2*i] = 1;
                middleSet[1+2*i] = 1;
            }
            else if(val == NEEDLENONE)
            {
                middleSet[0+2*i] = 0;
                middleSet[1+2*i] = 0;
            }
        }

        m_dispDatMiddle.clear();
        DispItem dispItemMiddle;
        double middleSpace = 0;
        double middleYSpace = 0;
        double ySpace = needleLayoutSpace12;

        for(unsigned int i = 0; i < sizeof(middleSet); i++)//12个针位设置，对应24根镇，一个针位上有2根针，每根针之间间距为1/2英寸
        {
            DispItem * pData = (DispItem *)(m_oneDispDat.data());
            char val = middleSet[i];

            if(val == 1)
            {
                for (int j = 0; j < stepsize; j++)
                {
                    dispItemMiddle = *pData;
                    dispItemMiddle.bx += middleSpace;
                    dispItemMiddle.ex += middleSpace;
                    dispItemMiddle.by -= ySpace;
                    dispItemMiddle.ey -= ySpace;

                    if (m_dispMinX > dispItemMiddle.bx) { m_dispMinX = dispItemMiddle.bx; }
                    if (m_dispMinX > dispItemMiddle.ex) { m_dispMinX = dispItemMiddle.ex; }
                    if (m_dispMaxX < dispItemMiddle.bx) { m_dispMaxX = dispItemMiddle.bx; }
                    if (m_dispMaxX < dispItemMiddle.ex) { m_dispMaxX = dispItemMiddle.ex; }
                    //后排无数据时
                    if(m_dispDatBehind.size() <= 0)
                    {
                        if (dispMinY > dispItemMiddle.by) { dispMinY = dispItemMiddle.by; }
                        if (dispMinY > dispItemMiddle.ey) { dispMinY = dispItemMiddle.ey; }
                        if (dispMaxY < dispItemMiddle.by) { dispMaxY = dispItemMiddle.by; }
                        if (dispMaxY < dispItemMiddle.ey) { dispMaxY = dispItemMiddle.ey; }
                        m_dispMinY = dispMinY;
                        m_dispMaxY = dispMaxY;
                    }

                    m_dispDatMiddle.append((char*)(&dispItemMiddle), sizeof(DispItem));
                    pData++;
                }

                //Y方向再循环多次
                for(int m = 0; m < circleNumMiddle; m++)
                {
                    DispItem * pData = (DispItem *)(m_oneDispDat.data());
                    middleYSpace = m * (m_maxY - m_minY) + (m_maxY - m_minY);
                    for (int j = 0; j < stepsize; j++)
                    {
                        dispItemMiddle = *pData;
                        dispItemMiddle.bx += middleSpace;
                        dispItemMiddle.ex += middleSpace;
                        dispItemMiddle.by -= (ySpace+middleYSpace);
                        dispItemMiddle.ey -= (ySpace+middleYSpace);

                        if (m_dispMinX > dispItemMiddle.bx) { m_dispMinX = dispItemMiddle.bx; }
                        if (m_dispMinX > dispItemMiddle.ex) { m_dispMinX = dispItemMiddle.ex; }
                        if (m_dispMaxX < dispItemMiddle.bx) { m_dispMaxX = dispItemMiddle.bx; }
                        if (m_dispMaxX < dispItemMiddle.ex) { m_dispMaxX = dispItemMiddle.ex; }
                        //后排无数据时
                        if(m_dispDatBehind.size() <= 0)
                        {
                            if (dispMinY > dispItemMiddle.by) { dispMinY = dispItemMiddle.by; }
                            if (dispMinY > dispItemMiddle.ey) { dispMinY = dispItemMiddle.ey; }
                            if (dispMaxY < dispItemMiddle.by) { dispMaxY = dispItemMiddle.by; }
                            if (dispMaxY < dispItemMiddle.ey) { dispMaxY = dispItemMiddle.ey; }
                            m_dispMinY = dispMinY;
                            m_dispMaxY = dispMaxY;
                        }

                        m_dispDatMiddle.append((char*)(&dispItemMiddle), sizeof(DispItem));
                        pData++;
                    }
                }
            }
            if(i % 2 == 0)
            {
                middleSpace += leftRightNeedleSpace;
            }
            else
            {
                //middleSpace += leftRightNeedleSpace*3;
                middleSpace = (i-i/2)*needlesSpace;
            }
        }
    }

    if(reDat == 0 || reDat == 3)
    {
        double dispMinY = S32_MAX;
        double dispMaxY = S32_MIN;

        //根据前中后排的设置，重置后排数据
        char behindSet[LAYOUTNEEDLENUM*2];
        memset((char*)behindSet,0,sizeof(behindSet));
        for(int i = 0; i < LAYOUTNEEDLENUM; i++)//12个针位设置，对应24根镇，一个针位上有2根针，每根针之间间距为1/2英寸
        {
            if(arrayNeedle3 == NULL)
                break;

            unsigned char val = *(arrayNeedle3+i);
            if(val == NEEDLELEFT)
            {
                behindSet[0+2*i] = 1;
                behindSet[1+2*i] = 0;
            }
            else if(val == NEEDLERIGHT)
            {
                behindSet[0+2*i] = 0;
                behindSet[1+2*i] = 1;
            }
            else if(val == NEEDLEDOUBLE)
            {
                behindSet[0+2*i] = 1;
                behindSet[1+2*i] = 1;
            }
            else if(val == NEEDLENONE)
            {
                behindSet[0+2*i] = 0;
                behindSet[1+2*i] = 0;
            }
        }

        m_dispDatBehind.clear();
        DispItem dispItemBehind;
        double behindSpace = 0;
        double behindYSpace = 0;
        double ySpace = needleLayoutSpace12+needleLayoutSpace23;
        for(unsigned int i = 0; i < sizeof(behindSet); i++)//12个针位设置，对应24根镇，一个针位上有2根针，每根针之间间距为1/2英寸
        {
            DispItem * pData = (DispItem *)(m_oneDispDat.data());
            char val = behindSet[i];

            if(val == 1)
            {
                for (int j = 0; j < stepsize; j++)
                {
                    dispItemBehind = *pData;
                    dispItemBehind.bx += behindSpace;
                    dispItemBehind.ex += behindSpace;
                    dispItemBehind.by -= ySpace;
                    dispItemBehind.ey -= ySpace;

                    if (m_dispMinX > dispItemBehind.bx) { m_dispMinX = dispItemBehind.bx; }
                    if (m_dispMinX > dispItemBehind.ex) { m_dispMinX = dispItemBehind.ex; }
                    if (m_dispMaxX < dispItemBehind.bx) { m_dispMaxX = dispItemBehind.bx; }
                    if (m_dispMaxX < dispItemBehind.ex) { m_dispMaxX = dispItemBehind.ex; }
                    if (dispMinY > dispItemBehind.by) { dispMinY = dispItemBehind.by; }
                    if (dispMinY > dispItemBehind.ey) { dispMinY = dispItemBehind.ey; }
                    if (dispMaxY < dispItemBehind.by) { dispMaxY = dispItemBehind.by; }
                    if (dispMaxY < dispItemBehind.ey) { dispMaxY = dispItemBehind.ey; }

                    m_dispDatBehind.append((char*)(&dispItemBehind), sizeof(DispItem));
                    pData++;
                }

                //Y方向再循环多次
                for(int m = 0; m < lastNum; m++)
                {
                    DispItem * pData = (DispItem *)(m_oneDispDat.data());
                    behindYSpace = m * (m_maxY - m_minY) + (m_maxY - m_minY);
                    for (int j = 0; j < stepsize; j++)
                    {
                        dispItemBehind = *pData;
                        dispItemBehind.bx += behindSpace;
                        dispItemBehind.ex += behindSpace;
                        dispItemBehind.by -= (ySpace+behindYSpace);
                        dispItemBehind.ey -= (ySpace+behindYSpace);

                        if (m_dispMinX > dispItemBehind.bx) { m_dispMinX = dispItemBehind.bx; }
                        if (m_dispMinX > dispItemBehind.ex) { m_dispMinX = dispItemBehind.ex; }
                        if (m_dispMaxX < dispItemBehind.bx) { m_dispMaxX = dispItemBehind.bx; }
                        if (m_dispMaxX < dispItemBehind.ex) { m_dispMaxX = dispItemBehind.ex; }
                        if (dispMinY > dispItemBehind.by) { dispMinY = dispItemBehind.by; }
                        if (dispMinY > dispItemBehind.ey) { dispMinY = dispItemBehind.ey; }
                        if (dispMaxY < dispItemBehind.by) { dispMaxY = dispItemBehind.by; }
                        if (dispMaxY < dispItemBehind.ey) { dispMaxY = dispItemBehind.ey; }

                        m_dispDatBehind.append((char*)(&dispItemBehind), sizeof(DispItem));
                        pData++;
                    }
                }
                m_dispMinY = dispMinY;
                m_dispMaxY = dispMaxY;
            }
            if(i % 2 == 0)
            {
                behindSpace += leftRightNeedleSpace;
            }
            else
            {
                //behindSpace += leftRightNeedleSpace*3;
                behindSpace = (i-i/2)*needlesSpace;
            }
        }
    }

    m_dispDat.clear();
    m_dispDat.append(m_dispDatFront);
    m_dispDat.append(m_dispDatMiddle);
    m_dispDat.append(m_dispDatBehind);

    if(m_dispDat.size() <= 0)
    {
        m_dispDat.append(m_oneDispDat);
        m_dispMaxX = m_maxX;
        m_dispMinX = m_minX;
        m_dispMaxY = m_maxY;
        m_dispMinY = m_minY;
    }
}

int EmbData::createDispFromEmbDs16DatForFlyShuttle(int initFlag)
{
    if(initFlag != 0)
    {
        if(m_dispDatFront.size() > 0 || m_dispDatMiddle.size() > 0 || m_dispDatBehind.size() > 0)
        {
            m_dispDat.clear();
            m_dispDat.append(m_dispDatFront);
            m_dispDat.append(m_dispDatMiddle);
            m_dispDat.append(m_dispDatBehind);
        }
        else
        {
            m_dispDat.clear();
            m_dispDat.append(m_oneDispDat);
        }
    }

    m_type = MACHINE_MULTINEEDLEROTARY;
    m_stitchIndex = 0;
    m_dispIndex = 0;

    // 图形显示区域
    int width = m_canvas.width();//留4个像素的边
    int height = m_canvas.height();//留4个像素的边

    if (width <= EMB_PREVIEW_SIDE*2 || height <= EMB_PREVIEW_SIDE*2)
    {
        qDebug("preview img too small");
        return -1;
    }

    //留边(否则实时跟踪笔会画出界)
    int viewSide = EMB_PREVIEW_SIDE;
    if(m_drawMode == DRAW_PREVIEW)
    {
        viewSide = 20;//预览模式时整区域留20像素绘制(原色显示)
    }
    int dpminx = viewSide;
    int dpmaxx = width - viewSide;
    int dpminy = viewSide;
    int dpmaxy = height - viewSide;

    //1:1显示无需留边
    //    int dpminx = 0;
    //    int dpmaxx = width;
    //    int dpminy = 0;
    //    int dpmaxy = height;

    // 计算缩放系数
    double factor, temp;
    if ((dpmaxx - dpminx) <= 0 || (dpmaxy - dpminy) <= 0)
    {
        return -1;
    }

    factor = (double)(fabs(m_dispMaxX-m_dispMinX)) / (dpmaxx - dpminx);      // 按框尺寸x计算的缩放系数
    temp =   (double)(fabs(m_dispMaxY-m_dispMinY)) / (dpmaxy - dpminy);      // 按框尺寸y计算的缩放系数

    if (temp >= factor)     // 使用较大的缩放系数
    {
        factor = temp;
    }

    m_factor = factor;

    // 计算显示参数，按照图形的实际位置显示（数据坐标零点对应图形中心）
    int dpx = (int)((dpminx+dpmaxx)/2 - ((m_dispMaxX+m_dispMinX)/factor)/2);
    //int dpy = (int)((dpminy+dpmaxy)/2 - ((m_dispMaxY+m_dispMinY)/factor)/2);
    int dpy = (int)((dpmaxy) - ((m_dispMaxY)/factor));//多针机不居中，顶端对齐

    if(g_emMacType == MACHINE_MULTINEEDLEROTARY)
    {
        emb_showDirY = 1;
    }

    int dispstepsize = m_dispDat.size()/sizeof(DispItem);
    if (dispstepsize <= 0)
    {
        return -1;
    }

    DispItem * pDispData = (DispItem *)(m_dispDat.data());
    for (int i = 0; i < dispstepsize; i++)
    {
        pDispData->bx = pDispData->bx / factor + dpx;
        pDispData->by = pDispData->by / factor + dpy;
        pDispData->ex = pDispData->ex / factor + dpx;
        pDispData->ey = pDispData->ey / factor + dpy;

        if (emb_showDirX == -1)
        {
            pDispData->bx = width - pDispData->bx;
            pDispData->ex = width - pDispData->ex;
        }
        if (emb_showDirY == -1)
        {
            pDispData->by = height - pDispData->by;
            pDispData->ey = height - pDispData->ey;

            if(g_emMacType == MACHINE_MULTINEEDLEROTARY)
            {
                double upSide = (height - dpmaxy);
                double dnSide = dpmaxy;

                if ((int)pDispData->by < upSide || (int)pDispData->by > dnSide)
                {
                    pDispData->rgb = qRgba(0,0,0,0);//设置透明色
                }

                if ((int)pDispData->ey < upSide || (int)pDispData->ey > dnSide)
                {
                    pDispData->rgb = qRgba(0,0,0,0);//设置透明色
                }
            }
        }

        pDispData++;
    }

    return 0;
}

//拐角分割/增加针步 （先分割再增加）
int EmbData::cornerAddNeedleStep(QByteArray &ds16dat)
{
    s8 cutFlag = m_cutcorner;// 拐角分割针步
    s8 addFlag = m_addcorner;// 拐角增加针步

    if ((addFlag=='0') && (cutFlag=='0'))
    {
        return -1;
    }

    int size = ds16dat.size();
    if (size <= (int)sizeof(Ds16Item))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int stepsize = size/sizeof(Ds16Item);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    Ds16Item * pData = (Ds16Item *)(ds16dat.data());
    Ds16Item * curDataPtr = pData;  //中间数据针步

    Ds16Item curDs16Item = {};      // 当前针步
    Ds16Item nextDs16Item = {};     // 下一针针步
    Ds16Item insDs16Item = {};      // 增加针步

    QByteArray tempDs16dat; // 临时数据
    tempDs16dat.clear();

    int cornered = 0;           // 增加数据标志

    if (1)
    {// 打印当前数据
        for (int j = 0; j < stepsize; j++)
        {
            memcpy(&curDs16Item,(curDataPtr+j),sizeof(Ds16Item));

            qDebug() << "idx="<<j
                     <<",ctrl="<<curDs16Item.ctrl
                    <<",dx="<<curDs16Item.dx
                   <<",dy="<<curDs16Item.dy
                  <<",dr="<<curDs16Item.dr;
        }
    }

    // 数据区
    for (int j = 0; j < stepsize; j++)
    {
        memcpy(&curDs16Item,(curDataPtr+j),sizeof(Ds16Item));

        if ((j==0) || (curDs16Item.ctrl != DATA_SEWING))
        {// 第一针&非缝纫针步 不做处理
            tempDs16dat.append((char*)(&curDs16Item), sizeof(Ds16Item));
            continue;
        }

        int k = j + 1;
        do
        {// 寻找下一个缝纫针步
            if (k >= (stepsize -1))
            {// 文件结束,指向第一针
                k = 0;
            }

            if ((curDataPtr + k)->ctrl == DATA_SEWING)
            {
                memcpy(&nextDs16Item,(curDataPtr + k),sizeof(Ds16Item));
                break;
            }
            k++;
        }while(1);

        if (k < j)
        {// 如果当前是最后一针,那么下一针是花样起始位置,重新计算下一针的dr
            double tar1 = atan2(curDs16Item.dy,curDs16Item.dx);
            double tar2 = atan2(nextDs16Item.dy,nextDs16Item.dx);
            double tar = tar2 - tar1;
            nextDs16Item.dr = (tar * 10000+0.5*(tar>0?1:-1));
        }

        if (qAbs(nextDs16Item.dr) >= ANGLECORR)
        {// 拐点角度大于60°,增加数据
            if (cutFlag != 0)
            {// 拐角分割针步有效
                cornered = 1;

                memcpy(&insDs16Item,(curDataPtr+j),sizeof(Ds16Item));
                insDs16Item.dx = insDs16Item.dx / 2;
                insDs16Item.dy = insDs16Item.dy / 2;
                insDs16Item.dr = 0;
                tempDs16dat.append((char*)(&insDs16Item), sizeof(Ds16Item));

                memcpy(&insDs16Item,(curDataPtr+j),sizeof(Ds16Item));
                insDs16Item.dx = insDs16Item.dx - (insDs16Item.dx / 2);
                insDs16Item.dy = insDs16Item.dy - (insDs16Item.dy / 2);
                tempDs16dat.append((char*)(&insDs16Item), sizeof(Ds16Item));
            }

            if (addFlag != 0)
            {// 拐角增加针步有效
                cornered = 1;

                memcpy(&insDs16Item,(curDataPtr+j),sizeof(Ds16Item));
                insDs16Item.dx = 0;
                insDs16Item.dr = 0;
                if (insDs16Item.dy > 0)
                {
                    insDs16Item.dy = 1;
                }
                else if (insDs16Item.dy < 0)
                {
                    insDs16Item.dy = -1;
                }
                else
                {
                    if (nextDs16Item.dy > 0)
                    {
                        insDs16Item.dy = 1;
                    }
                    else
                    {
                        insDs16Item.dy = -1;
                    }
                }
                tempDs16dat.append((char*)(&insDs16Item), sizeof(Ds16Item));
            }

        }
        else
        {// 拐角不大于60°,复制当前数据
            tempDs16dat.append((char*)(&curDs16Item), sizeof(Ds16Item));
        }
    }

    if (cornered != 0)
    {// 如果已经增加拐角数据,那么将新的数据复制给原花样
        size = tempDs16dat.size();
        stepsize = size/sizeof(Ds16Item);

        pData = (Ds16Item *)(tempDs16dat.data());
        curDataPtr = pData;  //中间数据针步

        ds16dat.clear();
        for (int j = 0; j < stepsize; j++)
        {
            memcpy(&curDs16Item,(curDataPtr+j),sizeof(Ds16Item));
            ds16dat.append((char*)(&curDs16Item), sizeof(Ds16Item));

            if (1)
            {// 打印处理后的数据
                qDebug() << "idx="<<j
                         <<",ctrl="<<curDs16Item.ctrl
                        <<",dx="<<curDs16Item.dx
                       <<",dy="<<curDs16Item.dy
                      <<",dr="<<curDs16Item.dr;
            }
        }
    }

    return 0;
}

// 角度修正 "x/y+-"版本 by刚哥
int EmbData::angleCorrection(QByteArray &ds16dat)
{
    int px = m_cornerPX;
    int nx = m_cornerNX;
    int py = m_cornerPY;
    int ny = m_cornerNY;

    qDebug()<<" px"<<px
           <<",nx"<<nx
          <<",py"<<py
         <<",ny"<<ny;

    if((px == 0) && (nx == 0) && (py == 0) && (ny == 0))
    {
        return -1;
    }

    if((px < 0) || (nx < 0) || (py < 0) || (ny < 0))
    {
        return -1;
    }

    int size = ds16dat.size();
    if (size <= (int)sizeof(Ds16Item))
    {
        qDebug("ary data less then head size");
        return -1;
    }

    int stepsize = size/sizeof(Ds16Item);
    if (stepsize <= 0)
    {
        qDebug("absdat data size err");
        return -1;
    }

    Ds16Item * pData = (Ds16Item *)(ds16dat.data());
    Ds16Item * curDataPtr = pData;  //中间数据针步

    Ds16Item curDs16Item = {};      // 当前针步
    Ds16Item nextDs16Item = {};     // 下一针针步

    QByteArray tempDs16dat;        // 临时数据
    tempDs16dat.clear();

    int cornered = 0;              // 修正数据标志
    int lastCornered = 0;          // 最后一针修正标志
    s16 cornerX = 0;               // 修正X
    s16 cornerY = 0;               // 修正Y

    if (0)
    {// 打印当前数据
        for (int j = 0; j < stepsize; j++)
        {
            memcpy(&curDs16Item,(curDataPtr+j),sizeof(Ds16Item));

            qDebug() << "idx="<<j
                     <<",ctrl="<<curDs16Item.ctrl
                    <<",dx="<<curDs16Item.dx
                   <<",dy="<<curDs16Item.dy
                  <<",len="<<curDs16Item.len
                 <<",dr="<<curDs16Item.dr;
        }
    }

    // 数据区
    for (int j = 0; j < stepsize; j++)
    {
        memcpy(&curDs16Item,(curDataPtr+j),sizeof(Ds16Item));

        if ((j==0) || (curDs16Item.ctrl != DATA_SEWING))
        {// 第一针&非缝纫针步 不做处理
            tempDs16dat.append((char*)(&curDs16Item), sizeof(Ds16Item));
            continue;
        }

        int k = j + 1;
        do
        {// 寻找下一个缝纫针步
            if (k >= (stepsize -1))
            {// 文件结束,指向第一针
                k = 0;
            }

            if ((curDataPtr + k)->ctrl == DATA_SEWING)
            {
                memcpy(&nextDs16Item,(curDataPtr + k),sizeof(Ds16Item));
                break;
            }
            k++;
        }while(1);

        if (k < j)
        {// 如果当前是最后一针,那么下一针是花样起始位置,重新计算下一针的dr
            double tar1 = atan2(curDs16Item.dy,curDs16Item.dx);
            double tar2 = atan2(nextDs16Item.dy,nextDs16Item.dx);
            double tar = tar2 - tar1;
            nextDs16Item.dr = (tar * 10000+0.5*(tar>0?1:-1));
        }

        if (qAbs(nextDs16Item.dr) >= ANGLECORR)
        {// 拐点角度大于60°,进行角度修正
            cornered = 1;
            if (k < j)
            {
                lastCornered = 1;          // 最后一针修正标志
            }

            // 计算角度修正量
            double  dtx = 0;           // 当前针步角度修正参数
            double  dty = 0;
            double  dtlen = 0;

            if (curDs16Item.dx > 0)
            {
                dtx = px;
            }
            else if (curDs16Item.dx < 0)
            {
                dtx = nx;
            }
            else
            {
                dtx = 0;
            }

            if (curDs16Item.dy > 0)
            {
                dty = py;
            }
            else if (curDs16Item.dy < 0)
            {
                dty = ny;
            }
            else
            {
                dty = 0;
            }

            dtlen = (dtx > dty)?dtx:dty;

            if (curDs16Item.len != 0)
            {
                cornerX = (curDs16Item.dx * dtlen) / curDs16Item.len; // 修正X
                cornerY = (curDs16Item.dy * dtlen) / curDs16Item.len; // 修正Y
            }
            else
            {
                cornerX = 0; // 修正X
                cornerY = 0; // 修正Y
            }

            curDs16Item.dx += cornerX;
            curDs16Item.dy += cornerY;
            curDs16Item.len = sqrt(curDs16Item.dx*curDs16Item.dx + curDs16Item.dy*curDs16Item.dy);
            tempDs16dat.append((char*)(&curDs16Item), sizeof(Ds16Item));           // 修正当前针步

            if (k > j)
            {
                nextDs16Item.dx -= cornerX;
                nextDs16Item.dy -= cornerY;
                nextDs16Item.len = sqrt(nextDs16Item.dx*nextDs16Item.dx + nextDs16Item.dy*nextDs16Item.dy);
                tempDs16dat.append((char*)(&nextDs16Item), sizeof(Ds16Item));           // 反向补偿下一个针步
                j++;
            }
        }
        else
        {// 拐角不大于60°,复制当前数据
            tempDs16dat.append((char*)(&curDs16Item), sizeof(Ds16Item));
        }
    }

    if (cornered != 0)
    {// 如果已经增加拐角数据,那么将新的数据复制给原花样
        size = tempDs16dat.size();
        stepsize = size/sizeof(Ds16Item);

        pData = (Ds16Item *)(tempDs16dat.data());
        curDataPtr = pData;  //中间数据针步

        ds16dat.clear();
        for (int j = 0; j < stepsize; j++)
        {
            memcpy(&curDs16Item,(curDataPtr+j),sizeof(Ds16Item));
            if ((j == 0) && (lastCornered != 0))
            { // 反向补偿第一个针步
                curDs16Item.dx -= cornerX;
                curDs16Item.dy -= cornerY;
                curDs16Item.len = sqrt(curDs16Item.dx*curDs16Item.dx + curDs16Item.dy*curDs16Item.dy);
            }

            ds16dat.append((char*)(&curDs16Item), sizeof(Ds16Item));

            if (0)
            {// 打印处理后的数据
                qDebug() << "idx="<<j
                         <<",ctrl="<<curDs16Item.ctrl
                        <<",dx="<<curDs16Item.dx
                       <<",dy="<<curDs16Item.dy
                      <<",dr="<<curDs16Item.dr;
            }
        }
    }

    return 0;
}
